android AlphabetListView

写道
有源码,在后面可以下载,这个方面的资料比较少,分享出来共同学习。
数据源是取出通讯录中的数据。
 
写道
AlphabetListView的实现:
 
package com.xiawenquan.test.widget;

import java.util.HashMap;

import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.xiawenquan.test.asyncqueryhandler.R;
import com.xiawenquan.test.widget.AlphabetView.OnTouchingLetterChangedListener;

public class AlphabetListView extends RelativeLayout {
	private Context mContext;
	private ListView mListView;
	private AlphabetView mAlphabetView;
	private HashMap<String, Integer> alphaIndexer;
	private TextView overlay;
	private Handler handler;
	private OverlayThread overlayThread;

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

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

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

	private void init(Context context) {

		mContext = context;
		LayoutInflater.from(context)
				.inflate(R.layout.alphabet_list, this, true);
		mListView = (ListView) findViewById(R.id.list_view);
		mAlphabetView = (AlphabetView) findViewById(R.id.alphabet_view);
		handler = new Handler();
		overlayThread = new OverlayThread();
		initOverlay();

		mAlphabetView
				.setOnTouchingLetterChangedListener(new OnTouchingLetterChangedListener() {

					public void onTouchingLetterChanged(String s) {
						if (alphaIndexer == null) {
							// throw new
							// RuntimeException("setAlphabetIndex方法未赋值");
						} else {
							final Integer position = alphaIndexer.get(s);
							if (position != null) {
								mListView.setSelection(position);
								overlay.setText(s);
								overlay.setVisibility(View.VISIBLE);
								handler.removeCallbacks(overlayThread);
								// 延迟一秒后执行,让overlay为不可见
								handler.postDelayed(overlayThread, 1500);
							} else if ("搜".equals(s)) {
								mListView.setSelection(0);
								overlay.setText(s);
								overlay.setVisibility(View.VISIBLE);
								handler.removeCallbacks(overlayThread);
								// 延迟一秒后执行,让overlay为不可见
								handler.postDelayed(overlayThread, 1500);
							}
						}
					}
				});
	}

	/**
	 * 设置首字母title再ListView中的位置
	 * 
	 * @param alphaIndexer
	 */
	public void setAlphabetIndex(HashMap<String, Integer> alphaIndexer) {
		this.alphaIndexer = alphaIndexer;
	}

	// 初始化汉语拼音首字母弹出提示框
	private void initOverlay() {
		final LayoutInflater inflater = LayoutInflater.from(mContext);
		overlay = (TextView) inflater.inflate(R.layout.overlay, null);
		overlay.setVisibility(View.INVISIBLE);
		final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
				WindowManager.LayoutParams.TYPE_APPLICATION,
				WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
						| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
				PixelFormat.TRANSLUCENT);
		final WindowManager windowManager = (WindowManager) mContext
				.getSystemService(Context.WINDOW_SERVICE);
		windowManager.addView(overlay, lp);
	}

	/**
	 * 设置overlay不可见
	 */
	public class OverlayThread implements Runnable {

		public void run() {
			overlay.setVisibility(View.GONE);
		}
	}

	public void setListViewBackgroundResource(int resid) {
		if (mListView != null) {
			mListView.setBackgroundResource(resid);
		}
	}

	public void setListViewBackgroundDrawable(Drawable d) {
		if (mListView != null) {
			mListView.setBackgroundDrawable(d);
		}
	}

	public void setListViewDivider(Drawable divider) {
		if (mListView != null) {
			mListView.setDivider(divider);
		}
	}

	public void setAdapter(BaseAdapter adapter) {
		if (mListView != null) {
			mListView.setAdapter(adapter);
		}
	}

	public void setListViewsetVisibility(int visibility) {
		if (mListView != null) {
			mListView.setVisibility(visibility);
		}
	}

	/**
	 * 设置字母列表默认颜色
	 * 
	 * @param color
	 */
	public void setDefaultColor(int color) {
		if (mAlphabetView != null) {
			mAlphabetView.setDefaultColor(color);
		}
	}

	/**
	 * 设置字母列表选中颜色
	 * 
	 * @param color
	 */
	public void setSelectColor(int color) {
		if (mAlphabetView != null) {
			mAlphabetView.setSelectColor(color);
		}
	}

	/**
	 * 设置字体大小
	 * 
	 * @param size
	 */
	public void setTextSize(float size) {
		if (mAlphabetView != null) {
			mAlphabetView.setTextSize(size);
		}
	}

	/**
	 * 设置搜索icon
	 * 
	 * @param resid
	 */
	public void setSearchIcon(int resid) {
		if (mAlphabetView != null) {
			mAlphabetView.setSearchIcon(resid);
		}
	}

	/**
	 * 设置搜索icon
	 * 
	 * @param resid
	 */
	public void setSearchIcon(Drawable drawable) {
		if (mAlphabetView != null) {
			mAlphabetView.setSearchIcon(drawable);
		}
	}

	/**
	 * 设置是否显示搜索icon
	 * 
	 * @param isShowSearchIcon
	 */
	public void setShowSearchIcon(boolean isShowSearchIcon) {
		if (mAlphabetView != null) {
			mAlphabetView.setShowSearchIcon(isShowSearchIcon);
		}
	}

	/**
	 * 设置索引浮窗字号
	 * 
	 * @param size
	 */
	public void setOverlayTextSize(float size) {
		if (overlay != null) {
			overlay.setTextSize(size);
		}
	}

	/**
	 * 设置索引浮窗字体颜色
	 * 
	 * @param color
	 */
	public void setOverlayTextColor(int color) {
		if (overlay != null) {
			overlay.setTextColor(color);
		}
	}

	/**
	 * 设置索引浮窗背景
	 * 
	 * @param resId
	 */
	public void setOverlayBackground(int resid) {
		if (overlay != null) {
			overlay.setBackgroundResource(resid);
		}
	}

	public void setOnItemClickListener(final OnItemClickListener listener) {
		if (mListView != null) {
			mListView
					.setOnItemClickListener(new ListView.OnItemClickListener() {

						public void onItemClick(AdapterView<?> arg0, View arg1,
								int arg2, long arg3) {
							if (listener != null) {
								listener.onItemClick(arg0, arg1, arg2, arg3);
							}

						}
					});
		}
	}

	public void setOnItemLongClickListener(
			final OnItemLongClickListener listener) {
		if (mListView != null) {
			mListView
					.setOnItemLongClickListener(new ListView.OnItemLongClickListener() {
						public boolean onItemLongClick(AdapterView<?> arg0,
								View arg1, int arg2, long arg3) {
							if (listener != null) {
								listener.onItemLongClick(arg0, arg1, arg2, arg3);
							}
							return false;
						}
					});
		}
	}

	public interface OnItemClickListener {
		public void onItemClick(AdapterView<?> parent, View view, int position,
				long id);
	}

	public interface OnItemLongClickListener {
		public void onItemLongClick(AdapterView<?> parent, View view,
				int position, long id);
	}

	public void setAlphabetViewVisibility(int visibility) {
		if (mAlphabetView != null) {
			mAlphabetView.setVisibility(visibility);
		}
	}
}

 

 

写道
AlphabetView 的实现:
 

 

package com.xiawenquan.test.widget;

import com.xiawenquan.test.asyncqueryhandler.R;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class AlphabetView extends View {
	private Bitmap bitmap = null;
	private OnTouchingLetterChangedListener onTouchingLetterChangedListener;
	private int choose = -1;
	private Paint paint = new Paint();
	private boolean isShowSearchIcon = true;
	private String[] alphabetList = { "#", "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" };
	private int mDefaultColor = Color.parseColor("#6a737d");
	private int mSelectColor = Color.parseColor("#3399ff");
	private float textSize = getResources().getDimension(
			R.dimen.alphabet_text_size);

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

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

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

	private void init(Context context) {
		bitmap = BitmapFactory.decodeResource(getResources(),
				R.drawable.alphabet_search_icon);
	}

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

		final int height = getHeight();
		final int width = getWidth();
		int singleHeight = height / alphabetList.length;
		final int size = alphabetList.length;
		for (int i = 0; i < size; i++) {
			if (alphabetList[i].equals("#")) {
				if (isShowSearchIcon) {
					float xPos = width / 2 - bitmap.getWidth() / 2;
					float yPos = bitmap.getHeight() / 2;

					// if(i == choose) {// 设置搜索icon选中效果
					// final Bitmap b =
					// BitmapFactory.decodeResource(getResources(),
					// R.drawable.icon);
					// canvas.drawBitmap(b, xPos, yPos, paint);
					// } else {
					canvas.drawBitmap(bitmap, xPos, yPos, paint);
					// }
					paint.reset();
				}
			} else {
				paint.setColor(mDefaultColor);
				paint.setAntiAlias(true);
				paint.setTextSize(textSize);
				if (i == choose) {
					paint.setColor(mSelectColor);
					paint.setFakeBoldText(true);
				}
				float xPos = width / 2 - paint.measureText(alphabetList[i]) / 2;
				float yPos = singleHeight * i + singleHeight;
				;
				canvas.drawText(alphabetList[i], xPos, yPos, paint);
				paint.reset();
			}
		}

	}

	/**
	 * 设置字母列表默认颜色
	 * 
	 * @param color
	 */
	protected void setDefaultColor(int color) {
		mDefaultColor = color;
	}

	/**
	 * 设置字母列表选中颜色
	 * 
	 * @param color
	 */
	protected void setSelectColor(int color) {
		mSelectColor = color;
	}

	/**
	 * 设置字体大小
	 * 
	 * @param size
	 */
	protected void setTextSize(float size) {
		textSize = size;
	}

	/**
	 * 设置搜索icon
	 * 
	 * @param resid
	 */
	protected void setSearchIcon(int resid) {
		bitmap = BitmapFactory.decodeResource(getResources(), resid);
	}

	/**
	 * 设置搜索icon
	 * 
	 * @param resid
	 */
	protected void setSearchIcon(Drawable drawable) {
		bitmap = ((BitmapDrawable) drawable).getBitmap();
	}

	/**
	 * 设置是否显示搜索icon
	 * 
	 * @param isShowSearchIcon
	 */
	public void setShowSearchIcon(boolean isShowSearchIcon) {
		this.isShowSearchIcon = isShowSearchIcon;
	}

	@Override
	public boolean dispatchTouchEvent(MotionEvent event) {
		final int action = event.getAction();
		final float y = event.getY();
		final int oldChoose = choose;
		final OnTouchingLetterChangedListener listener = onTouchingLetterChangedListener;
		final int c = (int) (y / getHeight() * alphabetList.length);

		switch (action) {
		case MotionEvent.ACTION_DOWN:
			if (oldChoose != c && listener != null) {
				if (c >= 0 && c < alphabetList.length) {
					if (alphabetList[c].equals("#")) {
						if (isShowSearchIcon) {
							listener.onTouchingLetterChanged("搜");
						}
					} else {
						listener.onTouchingLetterChanged(alphabetList[c]);
					}
					choose = c;
					setBackgroundResource(R.drawable.alphabet_list_bg);
					invalidate();
				}
			}

			break;
		case MotionEvent.ACTION_MOVE:
			if (oldChoose != c && listener != null) {
				if (c >= 0 && c < alphabetList.length) {
					if (alphabetList[c].equals("#")) {
						if (isShowSearchIcon) {
							listener.onTouchingLetterChanged("搜");
						}
					} else {
						listener.onTouchingLetterChanged(alphabetList[c]);
					}
					choose = c;
					invalidate();
				}
			}
			break;
		case MotionEvent.ACTION_UP:
			choose = -1;
			setBackgroundDrawable(null);
			invalidate();
			break;
		}
		return true;
	}

	public void setOnTouchingLetterChangedListener(
			OnTouchingLetterChangedListener onTouchingLetterChangedListener) {
		this.onTouchingLetterChangedListener = onTouchingLetterChangedListener;
	}

	public interface OnTouchingLetterChangedListener {
		public void onTouchingLetterChanged(String s);
	}
}

 

 

 

写道
Utils 的实现

 

package com.xiawenquan.test.utils;

import java.util.regex.Pattern;

public class Utils {
	
	/***
	 *获得汉语拼音首字母 
	 *不是字母返回#
	 *是字母返回字母
	 * */ 
	public static String  getAlpha(String str) {
		if (str == null) {
			return "#";
		}

		if (str.trim().length() == 0) {
			return "#";
		}

		char c = str.trim().substring(0, 1).charAt(0);
		// 正则表达式,判断首字母是否是英文字母
		Pattern pattern = Pattern.compile("^[A-Za-z]+$");
		if (pattern.matcher(c + "").matches()) {
			return (c + "").toUpperCase();
		} else {
			return "#";
		}
	}
	
}

 

写道
ConteactMode 的实现

 

 

package com.xiawenquan.test.mode;
/**
 * 封装数据的实体
 * @author xiawenquan
 */
public class ConteactMode {
	
	private String name;
	private String id;
	private String firstAlpha;
	private String phone;
	
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getFirstAlpha() {
		return firstAlpha;
	}
	public void setFirstAlpha(String firstAlpha) {
		this.firstAlpha = firstAlpha;
	}
	public String getPhone() {
		return phone;
	}
	public void setPhone(String phone) {
		this.phone = phone;
	}

}

 

 

 

package com.xiawenquan.test.adapter;

import java.util.ArrayList;

import com.xiawenquan.test.asyncqueryhandler.R;
import com.xiawenquan.test.mode.ConteactMode;

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

public class 
写道
ContactAdapter 的实现
 
extends BaseAdapter {

	private Context context;
	private ArrayList<ConteactMode> modes;
	
	public ContactAdapter(Context context){
		this.context = context;
	}
	
	
	public void setData(ArrayList<ConteactMode> modes){
		this.modes = modes;
	}
	
	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return modes != null && modes.size() > 0 ? modes.size() : 0;
	}

	@Override
	public Object getItem(int position) {
		// TODO Auto-generated method stub
		return modes != null && modes.size() > 0 ? modes.get(position) : null;
	}

	@Override
	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		ViewHolder holder ;
		if(convertView == null){
			holder = new ViewHolder();
			convertView = LayoutInflater.from(context).inflate(R.layout.alphalistview_item, null);
			
			holder.fistAlphaTextView = (TextView) convertView.findViewById(R.id.first_alpha);
			holder.nameTextView = (TextView) convertView.findViewById(R.id.name);
			holder.phoneTextView = (TextView) convertView.findViewById(R.id.phone);
			
			convertView.setTag(holder);
		}else{
			
			holder = (ViewHolder) convertView.getTag();
			
		}
		
		if(modes != null && modes.size() > 0){
			ConteactMode conteactMode = modes.get(position);
			if(conteactMode != null){
				
				//名称
				String name = conteactMode.getName();
				if(!TextUtils.isEmpty(name)){
					holder.nameTextView.setText(name);
				}
				
				//电话
				String phone = conteactMode.getPhone();
				if(!TextUtils.isEmpty(name)){
					holder.phoneTextView.setText(phone);
				}
				
				
				//首字母(前后两项对比字母是否相同,如果相同则过滤,否则添加进来)
				String currentAlpha = conteactMode.getFirstAlpha();
				ConteactMode mode = (position - 1) >= 0 ? modes.get(position - 1)  : null;
				String previewStr = "";
				if(mode != null){
					previewStr = mode.getFirstAlpha();
				}
				
				if (!previewStr.equals(currentAlpha)) {
					holder.fistAlphaTextView.setVisibility(View.VISIBLE);
					holder.fistAlphaTextView.setText(currentAlpha);
				}else{
					holder.fistAlphaTextView.setVisibility(View.GONE);
				}
			}
		}
		
		
		return convertView;
	}
	
	class ViewHolder{
		TextView fistAlphaTextView;
		TextView nameTextView;
		TextView phoneTextView;
	}

}

 

 

 

写道
MainActivity 的实现
 
package com.xiawenquan.test.asyncqueryhandler;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Pattern;

import com.xiawenquan.test.adapter.ContactAdapter;
import com.xiawenquan.test.mode.ConteactMode;
import com.xiawenquan.test.utils.Utils;
import com.xiawenquan.test.widget.AlphabetListView;

import android.app.Activity;
import android.content.AsyncQueryHandler;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Window;
import android.widget.CursorAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
/**
 * 简单使用AsyncQueryHandler
 * @author xianweuqan
 *
 */
@SuppressWarnings("unused")
public class MainActivity extends Activity {

	private ArrayList<ConteactMode> modes;
	protected QueryHandler mQueryHandler;
	protected Cursor mCursor = null;
	private AlphabetListView listView;
	private HashMap<String, Integer> alphaIndexer ;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//定义要查询的数据
		Uri uri = Uri.parse("content://com.android.contacts/data/phones");
		
		getWindow().requestFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		setContentView(R.layout.activity_main);

		modes = new ArrayList<ConteactMode>();
		listView = (AlphabetListView) findViewById(R.id.mylistview);
		//在这里加上加载框
		mQueryHandler = new QueryHandler(getContentResolver());
		query(uri);
	}

	/**
	 * 查询数据
	 * @param uri 数据的路径
	 */
	private void query(Uri uri) {
		
		String[] projection = { "_id", "display_name", "data1", "sort_key" };
		mQueryHandler.startQuery(0, null, uri, projection, null, null,
				"sort_key COLLATE LOCALIZED asc");//按字母排序

	}

	@Override
	protected void onStop() {
		super.onStop();
		if (mCursor != null) {
			mCursor.deactivate();
		}
	}

	class QueryHandler extends AsyncQueryHandler {

		public QueryHandler(ContentResolver cr) {
			super(cr);
		}

		@Override//查询完成后调用此方法
		protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
			super.onQueryComplete(token, cookie, cursor);
			setData(cursor);
			//在这里取消加载框
		}
	}
	
	/**
	 * 绑定数据
	 * @param cursor 游标
	 */
	  
	private void setData(Cursor cursor){
		if(cursor != null && cursor.getCount() > 0){
			if(alphaIndexer == null){
				alphaIndexer = new HashMap<String, Integer>();
				cursor.moveToFirst();
				for (int i = 0; i < cursor.getCount(); i++) {
					
					cursor.moveToPosition(i);
					//取出每一条数据
					String name = cursor.getString(1);
					String phone = cursor.getString(2);
					String sortKey = cursor.getString(3);
					
					//过滤"+86"
					if(phone.startsWith("+86")){
						phone = phone.substring(3);
					}
					
					//把数据封装在实体中
					ConteactMode mode = new ConteactMode();
					mode.setName(name);
					mode.setPhone(phone);
					
					String firstAlpha = Utils.getAlpha(sortKey);
					mode.setFirstAlpha(firstAlpha);
					//将封装的实体加到数组中
					modes.add(mode);
					
				}
				
				
				for(int i = 0 ; i < modes.size() ; i++){
					//处理当点击某一个字母后,其内容出现在屏幕可见状态下的最上面
					ConteactMode conteactMode = modes.get(i);
					String currentAlpha = conteactMode.getFirstAlpha();
					ConteactMode mode = (i - 1) >= 0 ? modes.get(i - 1)  : null;
					String previewStr = "";
					if(mode != null){
						previewStr = mode.getFirstAlpha();
					}
					if (!previewStr.equals(currentAlpha)) {
						alphaIndexer.put(currentAlpha,i);
					}
				}
				
				//把数据设置到adapter
				ContactAdapter adapter = new ContactAdapter(getApplicationContext());
				adapter.setData(modes);
				
				listView.setAlphabetIndex(alphaIndexer);
				listView.setAdapter(adapter);
				
			}
		}
	}
	
}

 

 

写道
最后附有源码,通过学习。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值