AndroidlistView按字母排序,关键字搜索功能

    xiaoxiao2025-08-06  7

    刚刚开始接触Android开发,新手从零开始,深知其中的心酸,分享一些自己遇到的问题,希望大家一起进步!

    SideBar.hava  实现字母排序:

    package com.keruixi.jobapply.view; import com.keruixi.jobapply.R; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Typeface; import android.graphics.drawable.ColorDrawable; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.widget.TextView; public class SideBar extends View { // 触摸事件 private OnTouchingLetterChangedListener onTouchingLetterChangedListener; // 26个字母 public static String[] b = { "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 choose = -1;// 选中 private Paint paint = new Paint(); private TextView mTextDialog; public void setTextView(TextView mTextDialog) { this.mTextDialog = mTextDialog; } public SideBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public SideBar(Context context, AttributeSet attrs) { super(context, attrs); } public SideBar(Context context) { super(context); } /** * 重写这个方法 */ protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 获取焦点改变背景颜色. int height = getHeight();// 获取对应高度 int width = getWidth(); // 获取对应宽度 int singleHeight = height / b.length;// 获取每一个字母的高度 for (int i = 0; i < b.length; i++) { paint.setColor(Color.rgb(33, 65, 98)); // paint.setColor(Color.WHITE); paint.setTypeface(Typeface.DEFAULT_BOLD); paint.setAntiAlias(true); paint.setTextSize(20); // 选中的状态 if (i == choose) { paint.setColor(Color.parseColor("#3399ff")); paint.setFakeBoldText(true); } // x坐标等于中间-字符串宽度的一半. float xPos = width / 2 - paint.measureText(b[i]) / 2; float yPos = singleHeight * i + singleHeight; canvas.drawText(b[i], xPos, yPos, paint); paint.reset();// 重置画笔 } } @Override public boolean dispatchTouchEvent(MotionEvent event) { final int action = event.getAction(); final float y = event.getY();// 点击y坐标 final int oldChoose = choose; final OnTouchingLetterChangedListener listener = onTouchingLetterChangedListener; final int c = (int) (y / getHeight() * b.length);// 点击y坐标所占总高度的比例*b数组的长度就等于点击b中的个数. switch (action) { case MotionEvent.ACTION_UP: setBackgroundDrawable(new ColorDrawable(0x00000000)); choose = -1;// invalidate(); if (mTextDialog != null) { mTextDialog.setVisibility(View.INVISIBLE); } break; default: setBackgroundResource(R.drawable.sidebar_background); if (oldChoose != c) { if (c >= 0 && c < b.length) { if (listener != null) { listener.onTouchingLetterChanged(b[c]); } if (mTextDialog != null) { mTextDialog.setText(b[c]); mTextDialog.setVisibility(View.VISIBLE); } choose = c; invalidate(); } } break; } return true; } /** * 向外公开的方法 * @param onTouchingLetterChangedListener */ public void setOnTouchingLetterChangedListener( OnTouchingLetterChangedListener onTouchingLetterChangedListener) { this.onTouchingLetterChangedListener = onTouchingLetterChangedListener; } /** * 接口 * @author coder */ public interface OnTouchingLetterChangedListener { public void onTouchingLetterChanged(String s); } }

    ClearEditText .java     完成关键字搜索功能:

    package com.keruixi.jobapply.view; import com.keruixi.jobapply.R; import android.content.Context; import android.graphics.drawable.Drawable; import android.text.Editable; import android.text.TextWatcher; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.View.OnFocusChangeListener; import android.view.animation.Animation; import android.view.animation.CycleInterpolator; import android.view.animation.TranslateAnimation; import android.widget.EditText; public class ClearEditText extends EditText implements           OnFocusChangeListener, TextWatcher {  /** * 删除按钮的引用 */     private Drawable mClearDrawable;        public ClearEditText(Context context) {      this(context, null);      }        public ClearEditText(Context context, AttributeSet attrs) {      //这里构造方法也很重要,不加这个很多属性不能再XML里面定义     this(context, attrs, android.R.attr.editTextStyle);      }           public ClearEditText(Context context, AttributeSet attrs, int defStyle) {         super(context, attrs, defStyle);         init();     }               private void init() {      //获取EditText的DrawableRight,假如没有设置我们就使用默认的图片     mClearDrawable = getCompoundDrawables()[2];          if (mClearDrawable == null) {          mClearDrawable = getResources()                      .getDrawable(R.drawable.emotionstore_progresscancelbtn);          }          mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight());          setClearIconVisible(false);          setOnFocusChangeListener(this);          addTextChangedListener(this);      }          /**      * 因为我们不能直接给EditText设置点击事件,所以我们用记住我们按下的位置来模拟点击事件      * 当我们按下的位置 在  EditText的宽度 - 图标到控件右边的间距 - 图标的宽度  和      * EditText的宽度 - 图标到控件右边的间距之间我们就算点击了图标,竖直方向没有考虑      */     @Override      public boolean onTouchEvent(MotionEvent event) {          if (getCompoundDrawables()[2] != null) {              if (event.getAction() == MotionEvent.ACTION_UP) {              boolean touchable = event.getX() > (getWidth()                          - getPaddingRight() - mClearDrawable.getIntrinsicWidth())                          && (event.getX() < ((getWidth() - getPaddingRight())));                 if (touchable) {                      this.setText("");                  }              }          }            return super.onTouchEvent(event);      }        /**      * 当ClearEditText焦点发生变化的时候,判断里面字符串长度设置清除图标的显示与隐藏      */     @Override      public void onFocusChange(View v, boolean hasFocus) {          if (hasFocus) {              setClearIconVisible(getText().length() > 0);          } else {              setClearIconVisible(false);          }      }          /**      * 设置清除图标的显示与隐藏,调用setCompoundDrawables为EditText绘制上去      * @param visible      */     protected void setClearIconVisible(boolean visible) {          Drawable right = visible ? mClearDrawable : null;          setCompoundDrawables(getCompoundDrawables()[0],                  getCompoundDrawables()[1], right, getCompoundDrawables()[3]);      }                 /**      * 当输入框里面内容发生变化的时候回调的方法      */     @Override      public void onTextChanged(CharSequence s, int start, int count,              int after) {          setClearIconVisible(s.length() > 0);      }        @Override      public void beforeTextChanged(CharSequence s, int start, int count,              int after) {                }        @Override      public void afterTextChanged(Editable s) {                }               /**      * 设置晃动动画      */     public void setShakeAnimation(){     this.setAnimation(shakeAnimation(5));     }               /**      * 晃动动画      * @param counts 1秒钟晃动多少下      * @return      */     public static Animation shakeAnimation(int counts){     Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0);     translateAnimation.setInterpolator(new CycleInterpolator(counts));     translateAnimation.setDuration(1000);     return translateAnimation;     }     }

    fragment_presson_info.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="match_parent"     android:orientation="vertical" >     <com.keruixi.jobapply.view.ClearEditText         android:id="@+id/filter_edit"         android:layout_width="match_parent"         android:layout_height="40dp"          android:background="@drawable/edittext_backgroup"          android:drawableLeft="@android:drawable/ic_menu_search"         android:hint="请输入关键字"         android:paddingBottom="@dimen/Fivedip"         android:paddingLeft="@dimen/Tendip"         android:paddingRight="@dimen/Fivedip"         android:paddingTop="@dimen/Fivedip"         android:singleLine="true"         android:textSize="15.0dip" />     <FrameLayout         android:layout_width="fill_parent"         android:layout_height="fill_parent" >         <ListView             android:id="@+id/country_lvcountry"             android:layout_width="fill_parent"             android:layout_height="fill_parent"             android:layout_gravity="center"             android:divider="@null"             android:scrollbars="@null" />         <TextView             android:id="@+id/dialog"             android:layout_width="80.0dip"             android:layout_height="80.0dip"             android:layout_gravity="center"             android:background="@drawable/show_head_toast_bg"             android:gravity="center"             android:textColor="#ffffffff"             android:textSize="30.0dip"             android:visibility="invisible" />         <com.keruixi.jobapply.view.SideBar             android:id="@+id/sidrbar"             android:layout_width="30.0dip"             android:layout_height="fill_parent"             android:layout_gravity="right|center" />     </FrameLayout> </LinearLayout>

    主页面   FragmentPersonInfo.java  代码:

    package com.keruixi.jobapply.fragment_addresslist; import java.util.ArrayList; import java.util.Collections; import java.util.List; import com.keruixi.jobapply.R; import com.keruixi.jobapply.adapter.SortAdapter; import com.keruixi.jobapply.entity.SortModel; import com.keruixi.jobapply.utils.CharacterParser; import com.keruixi.jobapply.utils.PinyinComparator; import com.keruixi.jobapply.view.ClearEditText; import com.keruixi.jobapply.view.SideBar; import com.keruixi.jobapply.view.SideBar.OnTouchingLetterChangedListener; import android.os.Bundle; import android.support.v4.app.Fragment; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ListView; import android.widget.TextView; public class Fragment_AddressList_Person_Contact extends Fragment { private ListView sortListView; private SideBar sideBar; private TextView dialog; private SortAdapter adapter; private ClearEditText mClearEditText; /** * 汉字转换成拼音的类 */ private CharacterParser characterParser; private List<SortModel> SourceDateList; /** * 根据拼音来排列ListView里面的数据类 */ private PinyinComparator pinyinComparator; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub View v = inflater.inflate(R.layout.fragment_address_fragmet_person_contact, null); initUI(v); return v; } private void initUI(View v) { // 实例化汉字转拼音类 characterParser = CharacterParser.getInstance(); pinyinComparator = new PinyinComparator(); sideBar = (SideBar) v.findViewById(R.id.sidrbar); dialog = (TextView) v.findViewById(R.id.dialog); sideBar.setTextView(dialog); // 设置右侧触摸监听 sideBar.setOnTouchingLetterChangedListener(new OnTouchingLetterChangedListener() { @Override public void onTouchingLetterChanged(String s) { // 该字母首次出现的位置 int position = adapter.getPositionForSection(s.charAt(0)); if (position != -1) { sortListView.setSelection(position); } } }); sortListView = (ListView) v.findViewById(R.id.country_lvcountry); SourceDateList = filledData(getResources().getStringArray(R.array.date)); // 根据a-z进行排序源数据 Collections.sort(SourceDateList, pinyinComparator); adapter = new SortAdapter(getActivity(), SourceDateList); sortListView.setAdapter(adapter); mClearEditText = (ClearEditText) v.findViewById(R.id.filter_edit); // 根据输入框输入值的改变来过滤搜索 mClearEditText.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { // 当输入框里面的值为空,更新为原来的列表,否则为过滤数据列表 filterData(s.toString()); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { } }); } /** * 为ListView填充数据 * @param date * @return */ private List<SortModel> filledData(String[] date) { List<SortModel> mSortList = new ArrayList<SortModel>(); for (int i = 0; i < date.length; i++) { SortModel sortModel = new SortModel(); sortModel.setName(date[i]); // 汉字转换成拼音 String pinyin = characterParser.getSelling(date[i]); String sortString = pinyin.substring(0, 1).toUpperCase(); // 正则表达式,判断首字母是否是英文字母 if (sortString.matches("[A-Z]")) { sortModel.setSortLetters(sortString.toUpperCase()); } else { sortModel.setSortLetters("#"); } mSortList.add(sortModel); } return mSortList; } /** * 根据输入框中的值来过滤数据并更新ListView * @param filterStr */ private void filterData(String filterStr) { List<SortModel> filterDateList = new ArrayList<SortModel>(); if (TextUtils.isEmpty(filterStr)) { filterDateList = SourceDateList; } else { filterDateList.clear(); for (SortModel sortModel : SourceDateList) { String name = sortModel.getName(); if (name.indexOf(filterStr.toString()) != -1 || characterParser.getSelling(name).startsWith(filterStr.toString())) { filterDateList.add(sortModel); } } } // 根据a-z进行排序 Collections.sort(filterDateList, pinyinComparator); adapter.updateListView(filterDateList); } }

    下面是效果图:

    转载请注明原文地址: https://ju.6miu.com/read-1301451.html
    最新回复(0)