- 浏览: 243815 次
- 性别:
- 来自: 贵州
-
文章分类
最新评论
-
夏文权:
增加事务处理
spring + mybatis 框架 -
vs0029:
这也太小儿科了
android ViewPager 和 listview的共存问题 -
于自水:
大神,同上啊,没解决啊!appid跟1楼的一样,我也郁闷好几天 ...
android 微信分享 -
lihaolee:
前辈你好,我最近正在做微信分享,自己申请了appid,包名签名 ...
android 微信分享 -
410812571:
你就是救世主。
android listview 加载图片错乱(错位)
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); } } } }
写道
最后附有源码,通过学习。
相关推荐
在Android开发中,串口通信(Serial Port Communication)是一种重要的技术,它允许设备之间通过串行接口进行数据交换。在Android Studio环境下实现串口通信,开发者可以构建与硬件设备交互的应用,例如读取传感器...
在现代的移动应用开发中,JavaScript与原生平台之间的交互变得越来越常见,特别是在使用Android的WebView组件时。本文将深入探讨如何使用JavaScript调用Android的方法,并传递JSON数据,以实现两者之间的高效通信。 ...
【Android扫雷游戏开发详解】 在移动开发领域,Android Studio是Google推出的官方集成开发环境(IDE),用于构建Android应用程序。本项目"Android扫雷游戏"就是利用Android Studio进行开发的一个实例,旨在帮助初学...
在Android开发中,为UI元素添加虚线、圆角和渐变效果是常见的需求,可以提升应用的视觉吸引力。下面将详细讲解如何实现这些效果。 ### 一、虚线(Dashed Line) 在Android中,我们可以使用`Shape Drawable`来创建...
# mv /opt/android-sdk/platforms/android-25/android-7.1.1/* /opt/android-sdk/platforms/android-25/ # rm -rf /opt/android-sdk/platforms/android-25/android-7.1.1 官网下载地址:...
Android 4.4.2 SDK(软件开发工具包)是Google为开发者提供的一个关键工具集,用于构建、调试和发布针对Android 4.4.2(KitKat)操作系统的应用程序。这个离线包包含了所有必要的组件,使得开发者无需连接到互联网...
在Android开发领域,初学者经常会面临许多挑战,如理解Android应用程序的基本架构、学习XML布局、掌握Java或Kotlin编程语言,以及如何与设备硬件交互等。"Android开发入门60个小案例+源代码"这个资源提供了丰富的...
源码里面有Bluetooth4_3/BLEDemo/Android_Lightblue.apk三个.前两个是BLE的demo。BLEDemo这个功能较Bluetooth4_3多一些,有兴趣的可以都看下。Android_Lightblue.apk是Android版的lightblue,在进行ble开发的时候用...
Android SipDemo是一个示例应用,它展示了如何在Android平台上实现网络电话功能,特别是针对Android 2.3(Gingerbread)及以上版本。这个项目基于Android的SIP(Session Initiation Protocol)API,这是一种用于...
第2篇为应用开发篇,通过实例介绍了Android UI布局、Android人机界面、手机硬件设备的使用、Android本地存储系统、Android中的数据库、多线程设计、Android传感器、Android游戏开发基础、Android与Internet,以及...
在Android平台上,即时通讯(Instant Messaging,简称IM)已经成为移动应用不可或缺的一部分,而结合视频通信功能则让用户体验更上一层楼。本项目“Android之基于RTP/RTSP即时通讯-Android源码”正是这样的一个解决...
《Android Studio项目源码解析与学习指南》 在Android应用开发的世界中,Android Studio作为官方推荐的集成开发环境(IDE),已经成为开发者们的首选工具。本文将深入探讨"50款Android studio项目源码.zip"这一资源...
在Android系统中,检测U盘(USB存储设备)的热插拔事件是一项常见的需求,尤其在开发与USB设备交互的应用时。"android检测U盘插拔事件"这个标题揭示了我们要探讨的核心技术点:如何在Android应用中监听并处理U盘的...
Android SDK是Android应用程序开发不可或缺的一部分,它为开发者提供了构建、测试和调试应用所需的各种工具。在本场景中,我们关注的是Android SDK的27版本,这对应于Android 8.1.0,也称为Oreo。这个版本的SDK包含...
在Android应用开发中,抽屉菜单(Drawer Menu)是一种常见的设计模式,用于提供导航功能,让用户可以从屏幕边缘滑出一个包含多个选项的列表。这种设计通常遵循Material Design指南,是Google推荐的Android应用界面...
在Android开发领域,Android Studio是谷歌官方推荐的集成开发环境(IDE),用于构建高质量的Android应用。本小案例将深入探讨如何使用Android Studio进行实际项目开发。以下将详细介绍Android Studio的一些核心功能和...
《VB for Android12.12:VB语言在Android开发中的新里程碑》 VB(Visual Basic)是微软公司推出的一种面向对象的编程语言,以其易学易用的特点深受程序员喜爱。随着移动应用市场的繁荣,VB也开始拓展到Android平台...
在Android平台上,开发一款“一键清理后台”应用可以帮助用户快速释放设备内存,提高系统运行速度。这个功能通常包括清理正在运行的应用程序、终止不必要的服务以及管理后台进程。下面将详细介绍如何在Android 4.4...
使用: export ANDROID_HOME="/opt/android-...# mv /opt/android-sdk/platforms/android-8.0.0 /opt/android-sdk/platforms/android-26 官网下载地址:https://dl.google.com/android/repository/platform-26_r01.zip