ListView按字母排序


源代码下载:点击打开链接

1、制作显示定位字母的SideBar。实现方法:新建一个类继承View。

package com.example.sortedlist;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;

public class SideBar extends View{
	// 触摸事件
	private OnTouchingLetterChangedListener onTouchingLetterChangedListener;
	private TextView mTextDialog; 
	public static String[] characters = { "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", "#" };

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

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

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

	public void setTextView(TextView mTextDialog) {
		this.mTextDialog = mTextDialog;
	}
	@SuppressLint("DrawAllocation")
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		int width = getWidth(); // 获取对应宽度
		int height = getHeight();// 获取对应高度
		int singleHeight = height / characters.length; // 获取每一个字母的高
		Paint paint = new Paint();
		
		for(int i = 0; i < characters.length; i++){
			paint.setTypeface(Typeface.DEFAULT_BOLD);
			paint.setAntiAlias(true);
			paint.setTextSize(12);
			paint.setColor(Color.rgb(33, 65, 98));
			
			float x = width / 2 - paint.measureText(characters[i]) / 2;
			float y = singleHeight * (i + 1); 
			canvas.drawText(characters[i], x, y, paint);
			paint.reset();
		}
	}
	@Override
	public boolean dispatchTouchEvent(MotionEvent event) {
		float y = event.getY();
		int pos = (int) (y / getHeight() * characters.length);
		
		switch (event.getAction()) {
		case MotionEvent.ACTION_UP:
			setBackgroundResource(R.drawable.sidebar);
			mTextDialog.setVisibility(View.INVISIBLE);
			break;
			
		default:
			setBackgroundResource(R.drawable.sidebar_hover);
			if(pos >= 0 && pos <= characters.length){
				
				if(onTouchingLetterChangedListener != null){
					onTouchingLetterChangedListener.onTouchingLetterChanged(characters[pos]);
				}
				if(mTextDialog != null){
					mTextDialog.setText(characters[pos]);
					mTextDialog.setVisibility(View.VISIBLE);
				}
			}
			break;
		}
		return true;
		
	}
	/**
	 * 向外公开的方法
	 * @param onTouchingLetterChangedListener
	 */
	public void setOnTouchingLetterChangedListener(OnTouchingLetterChangedListener onTouchingLetterChangedListener) {
		this.onTouchingLetterChangedListener = onTouchingLetterChangedListener;
	}

	/**
	 * 接口
	 * @author coder 
	 */
	public interface OnTouchingLetterChangedListener {
		public void onTouchingLetterChanged(String s);
	}
	
}
2、ListView Adapter实现

关键:判断getView方法中显示的View是否为属于的字母分类中的第一项,如果是第一项则显示导航字母TextView。

package com.example.sortedlist;

import java.util.Collections;
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.TextView;

public class MyAdapter extends BaseAdapter{

	LayoutInflater inflater;
	List<Item> data;
	
	public MyAdapter(Context context, List<Item> data){
		inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		this.data = data;
		Collections.sort(this.data, new PinyinComparator()); //根据首字母进行排序
	}

	@Override
	public int getCount() {
		return data.size();
	}

	@Override
	public Object getItem(int pos) {
		return data.get(pos);
	}

	@Override
	public long getItemId(int id) {
		return id;
	}

	@Override
	public View getView(int pos, View view, ViewGroup parent) {
		
		ViewHolder holder = null;
		if(view == null){
			holder = new ViewHolder();
			view = inflater.inflate(R.layout.listview_item, null);
			holder.letterTV = (TextView) view.findViewById(R.id.letter);
			holder.contentTV = (TextView) view.findViewById(R.id.content);
			view.setTag(holder);
		}
		holder = (ViewHolder) view.getTag();
		Item item = (Item) getItem(pos);
		if(isFirst(item, pos)){
			holder.letterTV.setVisibility(View.VISIBLE);
			holder.letterTV.setText(item.getLetter());
			holder.contentTV.setText(item.getContent());
		}else{
			holder.letterTV.setVisibility(View.GONE);
			holder.contentTV.setText(item.getContent());
		}
		return view;
	}
	
	
	//判断当前Item是否为当前开头字母的第一个Item
	public boolean isFirst(Item item, int position){
		int pos = getFirstPosAtList(item.getLetter());
		if(pos == position){
			return true;
		}
		return false;
	}
	//获取data中首字母字母为letter的item的位置
	public int getFirstPosAtList(String letter){
		for(int i = 0; i < data.size(); i++){
			Item item = data.get(i);
			if(item.getLetter().equals(letter)){
				return i;
			}
		}
		return -1;
	}
	class ViewHolder{
		TextView letterTV;
		TextView contentTV;
	}
}
MainActivity.java

package com.example.sortedlist;

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

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.widget.ListView;
import android.widget.TextView;

import com.example.sortedlist.SideBar.OnTouchingLetterChangedListener;

public class MainActivity extends Activity {
	private SideBar sideBar;
	private TextView textView;
	
	private ListView listView;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		sideBar = (SideBar) this.findViewById(R.id.sidebar);
		textView = (TextView) this.findViewById(R.id.label);
		sideBar.setTextView(textView);
		
		
		listView = (ListView) this.findViewById(R.id.listview);
		
		//列表数据
		List<String> data = new ArrayList<String>();
		data.add("我");
		data.add("喔");
		data.add("你");
		data.add("呢");
		data.add("找");
		data.add("白");
		data.add("才");
		data.add("嘛");
		data.add("有");
		data.add("啊");
		//将列表数据封装成对象,包含需要排列字段的首字母
		List<Item> items = filledData(data);
		
		final MyAdapter adapter = new MyAdapter(getApplicationContext(), items);
		listView.setAdapter(adapter);
		
		//设置右侧触摸监听
		sideBar.setOnTouchingLetterChangedListener(new OnTouchingLetterChangedListener() {
			@Override
			public void onTouchingLetterChanged(String s) {
				//该字母首次出现的位置
				int position = adapter.getFirstPosAtList(s);
				if(position != -1){
					listView.setSelection(position);
				}
			}
		});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	/**
	 * 为ListView填充数据(将列表数据封装成对象,包含需要排列字段的首字母)
	 * @param date
	 * @return
	 */
	private List<Item> filledData(List<String>  data){
		List<Item> mSortList = new ArrayList<Item>();
		
		for(int i=0; i<data.size(); i++){
			Item sortModel = new Item();
			sortModel.setContent(data.get(i));
			
			//汉字转换成拼音
			String pinyin = CnToSpellUtils.getPinYin(data.get(i));
			String sortString = pinyin.substring(0, 1).toUpperCase();
			// 正则表达式,判断首字母是否是英文字母
			if(sortString.matches("[A-Z]")){
				sortModel.setLetter(sortString.toUpperCase());
			}else{
				sortModel.setLetter("#");
			}
			mSortList.add(sortModel);
		}
		return mSortList;
	}
}






  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值