android ListView根据字母排序和定位

标签: android listview 字母 | 发表时间:2012-09-24 22:55 | 作者:
出处:http://www.iteye.com

基本上很多应用都是用了这个功能当数据多时方便快速查看浏览定位查询等,本案例功能比较简单,需要跟完善的话就要继续优化。

先上运行效果图如下:

 


 

 

第一步:首相自定义SideBar类继承View类,用于绘制A-Z文字控件,如下:

 

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.drawable.ColorDrawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.HeaderViewListAdapter;
import android.widget.ListView;
import android.widget.SectionIndexer;
import android.widget.TextView;

public class SideBar extends View {
	private char[] l;
	private SectionIndexer sectionIndexter = null;
	private ListView list;
	private TextView mDialogText;
	Bitmap mbitmap;
	private int type = 1;
	private int color = 0xff858c94;

	public SideBar(Context context) {
		super(context);
		init();
	}

	public SideBar(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	private void init() {

		l = new char[] { '!','A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
		 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
		  'W', 'X', 'Y', 'Z','#'};
		mbitmap = BitmapFactory.decodeResource(getResources(),
				R.drawable.scroll_bar_search_icon);
	}

	public SideBar(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}


	public void setListView(ListView _list) {
		list = _list;
		HeaderViewListAdapter ha = (HeaderViewListAdapter) _list
				.getAdapter();
		MyAdapter ad = (MyAdapter)ha.getWrappedAdapter();
		sectionIndexter = (SectionIndexer) ad;
		
	}

	public void setTextView(TextView mDialogText) {
		this.mDialogText = mDialogText;
	}

	public boolean onTouchEvent(MotionEvent event) {

		super.onTouchEvent(event);
		int i = (int) event.getY();

		int idx = i / (getMeasuredHeight() / l.length);
		if (idx >= l.length) {
			idx = l.length - 1;
		} else if (idx < 0) {
			idx = 0;
		}
		if (event.getAction() == MotionEvent.ACTION_DOWN
				|| event.getAction() == MotionEvent.ACTION_MOVE) {
			setBackgroundResource(R.drawable.scrollbar_bg);
			mDialogText.setVisibility(View.VISIBLE);
			if (idx == 0) {
				mDialogText.setText("Search");
				mDialogText.setTextSize(16);
			} else {
				mDialogText.setText(String.valueOf(l[idx]));
				mDialogText.setTextSize(34);
			}
			if (sectionIndexter == null) {

			

				sectionIndexter = (SectionIndexer) list.getAdapter();
				
			}
			int position = sectionIndexter.getPositionForSection(l[idx]);

			if (position == -1) {
				return true;
			}
			list.setSelection(position);
		} else {
			mDialogText.setVisibility(View.INVISIBLE);

		}
		if (event.getAction() == MotionEvent.ACTION_UP) {
			setBackgroundDrawable(new ColorDrawable(0x00000000));
		}
		return true;
	}

	protected void onDraw(Canvas canvas) {
		Paint paint = new Paint();
		paint.setColor(color);
		paint.setTextSize(12);
		paint.setStyle(Style.FILL);		
		paint.setTextAlign(Paint.Align.CENTER);
		float widthCenter = getMeasuredWidth() / 2;
		if (l.length > 0) {
			float height = getMeasuredHeight() / l.length;
			for (int i = 0; i < l.length; i++) {
				if (i == 0 && type != 2) {
					canvas.drawBitmap(mbitmap, widthCenter - 7, (i + 1)
							* height - height / 2, paint);
				} else
					canvas.drawText(String.valueOf(l[i]), widthCenter,
							(i + 1) * height, paint);
			}
		}
		this.invalidate();
		super.onDraw(canvas);
	}
}

 

 

第二步:设计xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ListView
        android:id="@+id/list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:divider="@null" />

    <com.example.listsildedel.SideBar
        android:id="@+id/sideBar"
        android:layout_width="25dp"
        android:layout_height="wrap_content"
        android:layout_gravity="right|center_vertical" />

</FrameLayout>

 

第三步:创建MyAdapter继承BaseAdapter并实现SectionIndexer接口注意这里一定要实现这个接口以便实现对应a-z的选择定位功能:

import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.SectionIndexer;
import android.widget.TextView;

public class MyAdapter extends BaseAdapter implements SectionIndexer{

	private List<Content> list = null;
	private Context mContext;
	private SectionIndexer mIndexer;
	
	public MyAdapter(Context mContext, List<Content> list) {
		this.mContext = mContext;
		this.list = list;

	}

	public int getCount() {
		return this.list.size();
	}

	public Object getItem(int position) {
		return null;
	}

	public long getItemId(int position) {
		return position;
	}

	public View getView(final int position, View view, ViewGroup arg2) {
		ViewHolder viewHolder = null;
		if (view == null) {
			viewHolder = new ViewHolder();
			view = LayoutInflater.from(mContext).inflate(R.layout.item, null);
			viewHolder.tvTitle = (TextView) view.findViewById(R.id.title);
			viewHolder.tvLetter = (TextView) view.findViewById(R.id.catalog);
			view.setTag(viewHolder);
		} else {
			viewHolder = (ViewHolder) view.getTag();
		}
		final Content mContent = list.get(position);
		if (position == 0) {
			viewHolder.tvLetter.setVisibility(View.VISIBLE);
			viewHolder.tvLetter.setText(mContent.getLetter());
		} else {
			String lastCatalog = list.get(position - 1).getLetter();
			if (mContent.getLetter().equals(lastCatalog)) {
				viewHolder.tvLetter.setVisibility(View.GONE);
			} else {
				viewHolder.tvLetter.setVisibility(View.VISIBLE);
				viewHolder.tvLetter.setText(mContent.getLetter());
			}
		}
	
		viewHolder.tvTitle.setText(this.list.get(position).getName());
		
		return view;

	}
	


	final static class ViewHolder {
		TextView tvTitle;
		TextView tvLetter;
	}


	public Object[] getSections() {
		// TODO Auto-generated method stub
		return null;
	}

	public int getSectionForPosition(int position) {
		
		return 0;
	}

	public int getPositionForSection(int section) {
		Content mContent;
		String l;
		if (section == '!') {
			return 0;
		} else {
			for (int i = 0; i < getCount(); i++) {
				mContent = (Content) list.get(i);
				l = mContent.getLetter();
				char firstChar = l.toUpperCase().charAt(0);
				if (firstChar == section) {
					return i + 1;
				}

			}
		}
		mContent = null;
		l = null;
		return -1;
	}
}

 第四步:编写MainActivity类

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout.LayoutParams;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {

	private ListView mListView;
	private SideBar indexBar;
	private WindowManager mWindowManager;
	private TextView mDialogText;
	private View head;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		 //启动activity时不自动弹出软键盘
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); 
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mListView = (ListView) this.findViewById(R.id.list);
		indexBar = (SideBar) findViewById(R.id.sideBar);
		mDialogText = (TextView) LayoutInflater.from(this).inflate(R.layout.list_position, null);
		head = LayoutInflater.from(this).inflate(R.layout.head, null);
		mListView.addHeaderView(head);
		mDialogText.setVisibility(View.INVISIBLE);
		mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
		WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
				WindowManager.LayoutParams.TYPE_APPLICATION,
				WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
						| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
				PixelFormat.TRANSLUCENT);
		mWindowManager.addView(mDialogText, lp);
		indexBar.setTextView(mDialogText);
		//初始化数据
		List<Content> list = new ArrayList<Content>();
		for (int i = 0; i < 10; i++) {
			Content m;
			if (i < 3)
				m = new Content("A", "选项" + i);
			else if (i < 6)
				m = new Content("F", "选项" + i);
			else
				m = new Content("D", "选项" + i);
			list.add(m);
		}
		//根据a-z进行排序
		Collections.sort(list, new PinyinComparator());
		// 实例化自定义内容适配类		
		MyAdapter adapter = new MyAdapter(this, list);
		// 为listView设置适配
		mListView.setAdapter(adapter);
		//设置SideBar的ListView内容实现点击a-z中任意一个进行定位
	    indexBar.setListView(mListView);		
	}

}
 源码已上传有需要参考的可以下载研究下,然后自己完善需要的功能。



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [android listview 字母] 推荐:

android ListView根据字母排序和定位

- - ITeye博客
基本上很多应用都是用了这个功能当数据多时方便快速查看浏览定位查询等,本案例功能比较简单,需要跟完善的话就要继续优化. 第一步:首相自定义SideBar类继承View类,用于绘制A-Z文字控件,如下:. 第三步:创建MyAdapter继承BaseAdapter并实现SectionIndexer接口注意这里一定要实现这个接口以便实现对应a-z的选择定位功能:.

Android下拉刷新ListView——RTPullListView

- - CSDN博客推荐文章
下拉刷新在越来越多的App中使用,已经形成一种默认的用户习惯,遇到列表显示的内容时,用户已经开始习惯性的拉拉. 之前在我的文章《 IOS学习笔记34—EGOTableViewPullRefresh实现下拉刷新》中介绍过如何在IOS上实现下拉刷新的功能. 今天主要介绍下在Android上实现下拉刷新的Demo,下拉控件参考自Github上开源项目 PullToRefresh,并做简单修改.

android 之如何优化 ListView

- - CSDN博客推荐文章
众所周知,在开发过程中,ListView的优化是比较重要的. ListView的提升效率,其实就是在于adapter中getView方法的优化,那么如何使的getView优化呢. 1、在getView() 中重用了convertView,很大程度上的减少了内存的消耗. 通过判断convertView是否为null,.

Android杂谈--ListView之BaseAdapter的使用

- - 博客园_首页
      前言      . 话说开发用了各种Adapter之后感觉用的最舒服的还是BaseAdapter,尽管使用起来比其他适配器有些麻烦,但是使用它却能实现很多自己喜欢的列表布局,比如ListView、GridView、Gallery、Spinner等等. 它是直接继承自接口类Adapter的,使用BaseAdapter时需要重写很多方法,其中最重要的当属getView,因为这会涉及到ListView优化等问题,其他的方法可以参考链接的文章.

ListView优化之内存优化

- - ITeye博客
• ListView视图缓存优化. • ListView异步加载优化. • ListView图片缓存. • 方法1 :  等比例缩小图片. 方法2 :  对图片采用软引用,及时地进行recyle ()操作. • 方法3 : 在页面切换时尽可能少地重复使用一些代码,比如.     :重复调用数据库,反复使用某些对象等等.

Sqlite数据库分页查询(ListView分页显示数据)

- - CSDN博客推荐文章
今天项目中遇到个问题,之前数据量不算多的时候,ListView显示正常,但是当数据量很大得分时候,进入画面,显示数据比较慢,. 而且不能放在UI线程中去拿数据,用子线程去拿把,画面出来了,但是数据要等很久才会出来,因此,这样给人的体验很不好,算不上好的设计. 因此,查了一下,关于数据库分页ListView分页.

优化listview的加载速度getview写法

- - Web前端 - ITeye博客
在android开发中Listview是一个很重要的组件,它以列表的形式根据数据的长自适应展示具体内容,用户可以自由的定义listview每一列的布局,但当listview有大量的数据需要加载的时候,会占据大量内存,影响性能,这时候就需要按需填充并重新使用view来减少对象的创建. 最快的方式是定义一个ViewHolder,将convetView的tag设置为ViewHolder,不为空时重新使用即可 static class ViewHolder { TextView text; ImageView icon; }.

字母自行车

- Zoe - 玩意儿
设计师将车架通过弯曲创造成一个个字母的形式,并且进行各种的着色,字母也就是本身车主的名字,浮动在车轮之间. 本文原始链接:http://www.cngadget.cn/rsz-juri-zaech-regina-bike.html. Read Your BooksCase:字母书架.

【动画】字母的演变

- 塔方 - 译言-每日精品译文推荐
译者 longtingfang. 这是马里兰大学Robert Fradkin教授“字母的历史”课的部分教材. 学术或语言性质的问题请email给Fradkin教授,他是马里兰大学亚洲与东欧语言系教授. 动画图像方面的问题请email给Charlie Seljos. 作者对宗教或神秘性质的字母和字符不能置评.

“新鲜出炉”的创意字母

- Guan - 译言-每日精品译文推荐
来源Creative Letters by Comming Soon. 你一定会喜欢这样的印刷设计,但当你知道这创意字母全是由实物创造而成的,是不是感到很不可思议呢. 这些是由一家比利时的工作室“新鲜出炉”为根特创意城打造的. 作者说:“根特创意城是由根特市议会(连同一些社会创意群体机构)首创举办的,主旨是设计未来充满挑战的都市生活,他们共同设计了根特城的未来.