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

刚刚开始接触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);
}
}


下面是效果图:


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值