• 热门专题

字母条索引定位

作者:  发布日期:2015-06-05 22:31:15
Tag标签:字母  索引  
  • 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;
    	}
    }
    

     

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规