笔记22 | 学习整理开源APP(BaseAnimation)程序源码“中的通讯录效果(三)

1.前言

整理学习”Android动画效果集合开源APP(BaseAnimation)程序源码“中的通讯录效果。 前人栽树:duguang 博客地址:http://blog.csdn.net/duguang77 下载地址:http://download.csdn.net/download/u011112840/6910683 后人乘凉:http://blog.csdn.net/xiangyong_1521/article/details/78273838


2.实现


3.目录

  • 3.1 A-Z的字母索引
  • 3.2 联系人界面ListView的数据填充
  • 3.3 联系人的搜索

3.1 A-Z的字母索引

通过自定义一个View界面,绘制一个A-Z竖向排列的布局,通过触摸事件监听,根据触摸的区域和字母高度的计算出position,再向联系人Listview提供一个方向输出position值!

>笔记20 | 学习整理开源APP(BaseAnimation)程序源码“中的通讯录效果(一)


3.2 通讯录界面ListView的数据填充

加载联系人的方法容易理解,排序》加载》处理

>笔记21 | 学习整理开源APP(BaseAnimation)程序源码“中的通讯录效果(二)


3.3 联系人的搜索

搜索部分难点是拿出搜索的内容,首先自定义了ClearEditText,给出了一个textchange的监听,然后进行匹配>筛选>排序>加载到联系人列表中。

  • xml
<com.example.book_mediarecorder.ClearEditText
        android:id="@+id/filter_edit"
        android:layout_marginTop="5dip"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/sorlistview_search_bar_edit_selector"
        android:drawableLeft="@drawable/sorlistview_search_bar_icon_normal"
        android:hint="请输入关键字"
        android:singleLine="true"
        android:textSize="15.0dip" />
  • MainActivity
mClearEditText = (ClearEditText) 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 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);
    }
  • 自定义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.sorlistview_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) { 
    } 
}

原文发布于微信公众号 - 项勇(xiangy_life)

原文发表时间:2017-10-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术小黑屋

自定义支持读取XML属性的View

在Android中,添加一个View很简单,简单的你可以简简单单地使用xml和一部分简单的java代码就可以搞定。 比如这样

832
来自专栏Android 开发学习

MVVM + data-binding 快速入门

1702
来自专栏Android开发实战

重新认识Android Context

Context在Android系统中的地位很重要,它几乎无所不能,但它也不是你想用就能随便用的,谨防使用不当引起的内存问题。我们总会忽略掉一些比较细节的东西,自...

723
来自专栏技术小黑屋

Android中实现用户无感知处理后台崩溃

正所谓,要想没有bug,就一行代码也不写。App到了用户的手里,肯定是崩溃越少越好。Android中的崩溃处理和iOS不太一样,iOS崩溃通常是闪退,而安卓会出...

461
来自专栏从零开始学 Web 前端

11 - JavaSE之GUI

PS: Panel 的 setBounds 方法中设置的位置大小是相对于相对装入的 Frame 窗口位置和大小的。

1005
来自专栏Jack的Android之旅

淘宝开源库VLayout实践

最近淘宝出了vlayout,刚开始看淘宝的文档的时候还是有点懵,后来自己也总结规划了一下,写了一个比较好看的demo,顺便在这里总结一下。

612
来自专栏Android机动车

手撸Router——解决跨模块下的页面跳转

正是由于将项目模块化拆分,各模块之间没有任何依赖关系,也互相不可见,那么从A模块的a界面跳转到B模块的b界面该怎么办呢?

733
来自专栏移动端开发

Android学习--RecyclerView

       前面一篇总结了ListView,在这篇我们总结一些这个RecyclerView,我们就从最基本的开始,安卓团队是将RecyclerView定义在s...

19610
来自专栏一“技”之长

iOS中动态更新补丁策略JSPatch运用基础一

        JSPatch是GitHub上一个开源的框架,其可以通过Objective-C的run-time机制动态的使用JavaScript调用与替换项目...

672
来自专栏腾讯Bugly的专栏

RecyclerView 必知必会

导语 RecyclerView是Android 5.0提出的新UI控件,可以用来代替传统的ListView。 Bugly之前也发过一篇相关文章,讲解了 Recy...

3587

扫码关注云+社区