自定义控件之android列表分组及字母导航

有了以上两篇文章的重构,现在把ListView分组列表重构为自定义控件就会非常简单,只需要把初始化操作放在自定义控件的构造函数里面。重构后的自定义控件以上一篇的注解重构为基础。

基本结构

这里首先贴上一张上篇文章重构后的activity的代码结构,相关的方法实现在之前两篇文章中都有贴出。

再贴一张重构后的View的结构。可见两者的结构都及其相似。不同的是上边的activity中有抽象方法getDataList(),而下边的没有,但是多了一个ILoadRulerData<T> iLoadData 类型的接口。用于加载数据。

且自定义View中把activity 中initdata()方法改为loaddata(),以供主动调用后开始加载数据。

重构后基本代码如下,省略了一部分和之前重复的代码:

首先是数据加载接口:

public interface ILoadRulerData<T> {

    public List<T> getDataList();

}

然后是自定义view的基本代码:

/**
 * @Description: 需要先调用 setiLoadData,设置获取数据的接口,然后再调用  loadData方法
 */
public class RulerView<T> extends LinearLayout{

    private View baseView;
    private TextView noDataView;

    private TextView RulerTag;
    private ProgressBarWithText progress;

    private ListView listView;

    private RulerWidget ruler;

    private ILoadRulerData<T> iLoadData;
    private List<T> originalList;
    public  List<RulerListDataWrapper<T>> dealedList;
    private HashMap<String, Integer> tagLocation = new HashMap<String, Integer>();
    private RulerAdapter<T> rulerAdapter;

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

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

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

    /**
    * @Description: 设置数据加载接口
    * @param
    * @return void
    */
    public void setiLoadData(ILoadRulerData<T> iLoadData) {
       this.iLoadData = iLoadData;
    }

    private void init(Context context){
       baseView = LayoutInflater.from(context).inflate(R.layout.g_ruler, null);
       noDataView = (TextView) baseView.findViewById(R.id.g_base_list_nodata);
       RulerTag = (TextView) baseView.findViewById(R.id.g_ruler_tag);
       progress = (ProgressBarWithText) baseView.findViewById(R.id.g_base_progressbar_withtext);
       listView = (ListView) baseView.findViewById(R.id.g_base_list);
       ruler = (RulerWidget) baseView.findViewById(R.id.g_ruler);
       progress.setVisibility(View.VISIBLE);
       RulerTag.setVisibility(View.GONE);
       noDataView.setVisibility(View.GONE);
       listView.setVisibility(View.GONE);
       ruler.setVisibility(View.GONE);
       addView(baseView, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    }

    public void loadData(){
       new GetDataAsyTask().execute();
    }

    。。。。。
        }

测试

布局

<?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"
    >

   <TextView
       android:layout_marginTop="10dp"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="wbxtest view"
       android:textColor="@color/g_black"
       />
   <******.ruler.view.RulerView
       android:id="@+id/test_ruler_view_id"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       />
</LinearLayout>

Activity

public class TestViewActivity extends Activity{

    private RulerView<TestAnnotationBo> rulerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.test_ruler_view);
        rulerView = (RulerView<TestAnnotationBo>) findViewById(R.id.test_ruler_view_id);
        rulerView.setiLoadData(new ILoadRulerData<TestAnnotationBo>() {

           @Override
           public List<TestAnnotationBo> getDataList() {

              return new TestAnnnoDao().getBoList();
           }
       });
        rulerView.loadData();

    }
}

此系列完毕。

时间: 2024-09-30 09:52:22

自定义控件之android列表分组及字母导航的相关文章

android列表分组及字母导航-重构(2)-注解

上篇文章对listView 分组和字母索引导航进行了重构,重构之后,使新的实现只依赖于接口,而不是具体的Bo.但是还是要求原始的数据Bo实现接口或者继承抽象类.能不能把这一步也简化呢,只需要原始的数据Bolist? 答案是可以的,可以使用注解,也就是annnotion. 想法和思路 Java注解又叫java标注,java提供了一套机制,使得我们可以对方法.类.参数.包.域以及变量等添加标准(即附上某些信息).且在以后某个时段通过反射将标注的信息提取出来以供使用. 分组listView 在上次重构

android之ListView分组及字母索引导航(2)重构-接口

上篇文章对listView 分组和字母索引导航的实现思路做了分析,并依照思路一步步实现,到最后已经较好的实现了全部功能.但是仔细研究就会发现其实现不够好,主要问题: 1.               对于一个使用范围比较广泛的布局,以上实现不够通用,尤其是Bo中需加上一些多余的字段,这些字字段本身并没有意义. 2.               代码都糅合在activity中. 针对以上两点做一些代码重构.首先我们把其优化为一个通用的activity.这样做成通用的View就很容易:然后对代码进行

论字母导航的重要性,我们来实现一个联系人字母导航列表吧!

论字母导航的重要性,我们来实现一个联系人字母导航列表吧! 说起这个字母导航,我相信大家都不陌生,不论是联系人列表还是城市列表,基本上都是需要字母导航,那我们就有必要来研究一下这个思路的探索了,毕竟这是一个非常常用的功能,如果现在把轮子造好,那以后也可以节省很多的时间,同时,我们把思路理清楚了,对我们以后的帮助也是很大的,那好,既然如此,我们就一起来探索一下吧! 我们首选新建一个项目--LettersNavigation OK,工程建立好之后我们来思考一下这个功能的一个实现逻辑 逻辑不是很难,那我

Android仿联系人列表分组悬浮列表,PinnedHeaderListView源码解析

github地址:https://github.com/JimiSmith/PinnedHeaderListView 关于实现类似联系人列表,组的头部总是悬浮在listview最顶部的效果,github上面有两个比较好的实现,分别是pinnedSectionListview和pinnedHeaderListView,之所以选择后者进行源码解析,是因为后者的源码比较简单,便于我们理解实现的精髓所在. 如果你想直接实现Android仿联系人列表分组悬浮列表, 自定义PinnedHeaderListV

ListView 字母导航排序

一.概述 ListView字母导航排序,网上已经有很多代码和博客了, 这篇博文也是照搬网上的.  之所以写到这里,不是为了说明什么,只是为了以后自己查阅方便.本来公司要求实现expandablelistview + 字母导航的, 这里先抄袭一下 ListView的 字母导航, 此处没有实现挤压效果. 二.代码 package com.example.sortlistview; import android.content.Context; import android.graphics.Canv

浅谈android中手机联系人字母索引表的实现

实际上字母索引表的效果,可以说在现在的众多APP中使用的非常流行,比如支付宝,微信中的联系人,还有购物,买票的APP中选择全国城市,切换城市的时候,这时候的城市也就是按照一个字母索引的顺序来显示,看起来是很方便的.其实这种字母索引表的效果最开始是出现在微信的联系人中.因为觉得这种效果功能在今后的项目中可以说是非常常见,可能会用的上,所以准备来波博客讲述一下实现的原理,一来方便以后自己复习,二来如果能够帮助一些android路上奋斗小伙伴也是蛮有意义的. 下面我们先来看下效果图, 看完效果图后我们

如何获取android手机联系人并按字母展示(三)

如果获取contact的头像信息并展示: 如何根据photoId来获取bitmap: public static Bitmap getContactPhoto(Context context, long photoId, BitmapFactory.Options options) { if (photoId < 0) { return null; } Cursor cursor = null; try { cursor = context.getContentResolver().query(

android 列表图片优化经历

先上个优化之后的fps图,丝滑流畅:具体实现请看最终优化后的app 背景:一个通讯录app(开源地址),每次登陆时,针对每个用户,如果头像图片不在本地,则生成一个异步下载任务(AsyncTask). tips:判断图片是否在本地,咱使用的方法: 根据该图片的url,比如 http://images0.cnblogs.com/blog2015/339868/201507/230955108345303.png 截取com之后的字符串,则本地的地址是:app的包名/files/blog2015/33

字母导航跳转react核心代码

componentDidMount() { this.move(); } skipToDep(e) { let dom = document.getElementById(e); // 获取要跳至的字母节点 if (e === '#') { this.props.scroller.scrollTo(0, 0); } else { this.props.scroller.scrollTo(0, -dom.offsetTop); } } move() { // 监听字母导航列表的touchmove事