码迷,mamicode.com
首页 > 其他好文 > 详细

字母条索引定位

时间:2015-06-05 19:46:27      阅读:110      评论:0      收藏:0      [点我收藏+]

标签:字母条 索引 adapter   onmeasure   

技术分享

activity_main.xml

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

    <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </ListView>

    <com.atguigu.quickindex.QuickIndexBar
        android:id="@+id/qucikIndexBar"
        android:layout_width="35dp"
        android:layout_height="match_parent"
        android:layout_alignParentRight="true"
        android:background="#CFCFCF" />

    <TextView
        android:id="@+id/currentIndex"
        android:layout_width="120dp"
        android:layout_height="105dp"
        android:layout_centerInParent="true"
        android:background="@drawable/bg_index"
        android:gravity="center"
        android:text="A"
        android:textColor="#ffffff"
        android:textSize="30sp"
        android:visibility="gone" />
</RelativeLayout>

item_friend.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >
    
    <TextView 
        android:id="@+id/index"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="5dp"
        android:paddingBottom="5dp"
        android:paddingLeft="10dp"
        android:text="A"
        android:textColor="#ffffff"
        android:background="#666666"
        android:textSize="18sp"/>
    <TextView 
        android:id="@+id/name"
        android:layout_height="wrap_content"
       	android:layout_width="match_parent"
       	android:padding="10dp"
        android:text="adasd"
        android:textColor="#666666"
        android:textSize="20sp"/>
</LinearLayout>

MainActivity

package com.atguigu.quickindex;

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

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

import com.atguigu.quickindex.QuickIndexBar.OnTouchIndexChange;

public class MainActivity extends Activity {

	private ListView listView;
	private QuickIndexBar qucikIndexBar;
	private TextView currentIndex;
	// 数据集合
	private List<Friend> friends = new ArrayList<Friend>();
	// 适配器
	private FriendAdapter adapter;
	private Handler handler = new Handler();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// 加载主布局
		setContentView(R.layout.activity_main);
		// 初始化控件
		init();
	}

	private void init() {
		/** 初始化布局视图 */
		listView = (ListView) findViewById(R.id.listview);
		qucikIndexBar = (QuickIndexBar) findViewById(R.id.qucikIndexBar);
		currentIndex = (TextView) findViewById(R.id.currentIndex);
		/** 初始化数据 */
		initData();
		// 创建适配器
		adapter = new FriendAdapter();
		// 设置适配器
		listView.setAdapter(adapter);

		// 设置触摸的字母变化的监听
		qucikIndexBar.setOnTouchIndexChange(new OnTouchIndexChange() {
			@Override
			public void onChange(String word) {// word为当前触摸的字母
				// 显示当前触摸的字母
				showInexWord(word);
				// 使用列表定位到对应的列表项
				locationWord(word);
			}
		});
	}

	private void locationWord(String word) {
		for (int i = 0; i < friends.size(); i++) {
			//名字首字母
			String firstWord = friends.get(i).getPinyin().charAt(0) + "";
			if (firstWord.equals(word)) {
				//定位到item的位置
				listView.setSelection(i);
				return;
			}
		}
	}

	private void showInexWord(String word) {
		currentIndex.setVisibility(View.VISIBLE);
		currentIndex.setText(word);
		//停掉所用handler的消息,防止内存泄露
		handler.removeCallbacksAndMessages(null);
		//2秒的定时器
		handler.postDelayed(new Runnable() {
			@Override
			public void run() {
				currentIndex.setVisibility(View.GONE);
			}
		}, 2000);
	}

	private void initData() {
		// 虚拟数据
		friends.add(new Friend("张晓飞"));
		friends.add(new Friend("杨光福"));
		friends.add(new Friend("胡继群"));
		friends.add(new Friend("刘畅"));

		friends.add(new Friend("钟泽兴"));
		friends.add(new Friend("尹革新"));
		friends.add(new Friend("安传鑫"));
		friends.add(new Friend("张骞壬"));

		friends.add(new Friend("温松"));
		friends.add(new Friend("李凤秋"));
		friends.add(new Friend("刘甫"));
		friends.add(new Friend("娄全超"));
		friends.add(new Friend("张猛"));

		friends.add(new Friend("王英杰"));
		friends.add(new Friend("李振南"));
		friends.add(new Friend("孙仁政"));
		friends.add(new Friend("唐春雷"));
		friends.add(new Friend("牛鹏伟"));
		friends.add(new Friend("姜宇航"));

		friends.add(new Friend("刘挺"));
		friends.add(new Friend("张洪瑞"));
		friends.add(new Friend("张建忠"));
		friends.add(new Friend("侯亚帅"));
		friends.add(new Friend("刘帅"));

		friends.add(new Friend("乔竞飞"));
		friends.add(new Friend("徐雨健"));
		friends.add(new Friend("吴亮"));
		friends.add(new Friend("王兆霖"));

		friends.add(new Friend("阿三"));
		friends.add(new Friend("二毛"));

		/**
		 * Comparable。可以让自定义对象实现一个Comparable接口,这个接口只有一个方法comparableTo(Object o)
		 * 
		 * 其规则是当前对象与o对象进行比较,返回一个int值,系统根据此值进行排序。
		 * 
		 * 如当前对象>o对象,则返回值>0;
		 * 
		 * 如当前对象=o对象,则返回值=0;
		 * 
		 * 如当前对象<o对象,则返回值<0;
		 */
		Collections.sort(friends);
	}

	/**
	 * adapter
	 */
	class FriendAdapter extends BaseAdapter {

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

		@Override
		public Object getItem(int position) {
			return friends.get(position);
		}

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

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			ViewHolder holder = null;
			if (convertView == null) {
				convertView = View.inflate(getApplicationContext(),
						R.layout.item_friend, null);
				holder = new ViewHolder();
				holder.index = (TextView) convertView.findViewById(R.id.index);
				holder.name = (TextView) convertView.findViewById(R.id.name);
				convertView.setTag(holder);
			} else {
				holder = (ViewHolder) convertView.getTag();
			}

			Friend friend = friends.get(position);
			String firstWord = friend.getPinyin().charAt(0) + "";// 得到拼音首字母

			if (position == 0) {// 如果是第一个, 显示首字母View
				holder.index.setVisibility(View.VISIBLE);
			} else {// 如果不是第一个
				// 上一项的拼音首字母
				String preFirstWord = friends.get(position - 1).getPinyin()
						.charAt(0)
						+ "";
				if (firstWord.equals(preFirstWord)) {// 如果当前的与上一个相同, 不显示首字母View
					holder.index.setVisibility(View.GONE);
				} else {// 否则, 显示
					holder.index.setVisibility(View.VISIBLE);
				}
			}

			holder.index.setText(firstWord);
			holder.name.setText(friend.getName());

			return convertView;
		}

		class ViewHolder {
			TextView index, name;
		}
	}
}

QuickIndexBar

package com.atguigu.quickindex;

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

/**
 * 自定义快速索引的View
 */
public class QuickIndexBar extends View {

	public QuickIndexBar(Context context, AttributeSet attrs) {
		super(context, attrs);
		// 初始化paint
		paint = new Paint();
		paint.setAntiAlias(true);// 抗据齿
	}

	private Paint paint;

	// 字母的宽、高
	private int cellWidth;
	private int cellHeight;
	private int touchIndex = -1;
	// 字体选中、非选中大小
	private int textSize;
	private int textTouchSize;

	private String[] indexArr = { "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" };

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);

		cellWidth = this.getMeasuredWidth();
		cellHeight = this.getMeasuredHeight() / indexArr.length;

		textSize = cellHeight - 5;
		textTouchSize = cellHeight + 5;
	}

	@SuppressLint("DrawAllocation")
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);

		for (int i = 0; i < indexArr.length; i++) {
			// 字母的字体大小
			paint.setTextSize(i == touchIndex ? textTouchSize : textSize);
			// 字母的字体颜色
			paint.setColor(i == touchIndex ? Color.parseColor("#666666")
					: Color.WHITE);
			// 计算字母显示的宽高
			Rect bounds = new Rect();
			//paint.getTextBounds(str, 0, str.length(), rect); 
			paint.getTextBounds(indexArr[i], 0, 1, bounds);
			int width = bounds.width();
			int height = bounds.height();
			// 计算字母绘制的坐标
			float x = cellWidth / 2 - width / 2;
			float y = i * cellHeight + cellHeight / 2 + height / 2;
			// 绘制字母文本
			canvas.drawText(indexArr[i], x, y, paint);
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {

		// 相对于当前View的事件y坐标
		int y = (int) event.getY();

		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
		case MotionEvent.ACTION_MOVE:
			// 如果没有在当前字母的区域内, 就需要更新touchIndex, 并重绘
			int index = y / cellHeight;
			if (index != touchIndex) {
				touchIndex = index;
				if (touchIndex >= indexArr.length)
					touchIndex = indexArr.length - 1;
				// 强制重绘
				invalidate();
				// 如果有监听器, 调用监听器的回调方法
				if (onTouchIndexChange != null) {
					onTouchIndexChange.onChange(indexArr[touchIndex]);
				}
			}
			break;
		case MotionEvent.ACTION_UP:
			touchIndex = -1;
			// 强制重绘
			invalidate();
			break;
		default:
			break;
		}
		return true;
	}

	private OnTouchIndexChange onTouchIndexChange;

	public void setOnTouchIndexChange(OnTouchIndexChange onTouchIndexChange) {
		this.onTouchIndexChange = onTouchIndexChange;
	}

	public interface OnTouchIndexChange {
		public void onChange(String word);
	}
}

Friend

package com.atguigu.quickindex;

/**
 * 好友信息对象
 */
public class Friend implements Comparable<Friend> {

	private String name;//姓名
	private String pinyin;//姓名对应的拼音

	public Friend(String name) {
		super();
		this.name = name;
		//通过名字得到对应的拼音
		this.pinyin = PinYinUtils.getPinYin(name);
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPinyin() {
		return pinyin;
	}

	public void setPinyin(String pinyin) {
		this.pinyin = pinyin;
	}

	@Override
	public String toString() {
		return "Friend [name=" + name + ", pinyin=" + pinyin + "]";
	}

	/**
	 * 此接口强行对实现它的每个类的对象进行整体排序。此排序被称为该类的自然排序 ,类的 compareTo 方法被称为它的自然比较方法 。
	 */
	@Override
	public int compareTo(Friend another) {
		return pinyin.compareTo(another.getPinyin());
	}
}

PinYinUtils

package com.atguigu.quickindex;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

/**
 * 将汉字转换为拼音
 */
public class PinYinUtils {
	/**
	 * 得到指定汉字的拼音
	 * 注意:不应该被频繁调用,它消耗一定内存
	 */
	public static String getPinYin(String hanzi){
		String pinyin = "";
		
		HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();//控制转换是否大小写,是否带音标
		format.setCaseType(HanyuPinyinCaseType.UPPERCASE);//大写
		format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
		
		//由于不能直接对多个汉字转换,只能对单个汉字转换
		char[] arr = hanzi.toCharArray();
		for (int i = 0; i < arr.length; i++) {
			if(Character.isWhitespace(arr[i]))continue;//如果是空格,则不处理,进行下次遍历
			
			//汉字是2个字节存储,肯定大于127,所以大于127就可以当为汉字转换
			if(arr[i]>127){
				try {
					//由于多音字的存在,单 dan shan
					String[] pinyinArr = PinyinHelper.toHanyuPinyinStringArray(arr[i], format);
					
					if(pinyinArr!=null){
						pinyin += pinyinArr[0];
					}else {
						pinyin += arr[i];
					}
				} catch (BadHanyuPinyinOutputFormatCombination e) {
					e.printStackTrace();
					//不是正确的汉字
					pinyin += arr[i];
				}
			}else {
				//不是汉字,
				pinyin += arr[i];
			}
		}
		return pinyin;
	}
}


字母条索引定位

标签:字母条 索引 adapter   onmeasure   

原文地址:http://blog.csdn.net/u013210620/article/details/46380683

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!