关于ListView的知识(3)

ListView中getView中很冗余同时很多不好用的方法,我们需要复写BaseAdapter

-----他配合BaseHolder使用
-----该基类有为可以多提供一个item既Load_more
-----  暴露protected abstract BaseHolder<T> getItemHolder(int position);
        让使用者根据postion使用不同的Item
------ /**
     * 如果孩子有item的点击事件,复写此方法即可
     */
    protected void onNoramlItemClick(AdapterView<?> parent, View view, int position, long id)
    {
    }
-----
使用--------------------------------------------------------------------------------
=

    class HomeAdapter extends AppListAdapter
    {

        public HomeAdapter(AbsListView listView, List<AppInfoBean> datas) {
            super(listView, datas);
            // TODO Auto-generated constructor stub
        }

        @Override
        protected List<AppInfoBean> onLoadMoreData() throws Exception
        {
            return loadMoreData(mDatas.size());
        }

    }
------------------------------------------------------------------------------------
======================================================
public class AppListAdapter extends SuperBaseAdapter<AppInfoBean> {
    private List<AppInfoBean> mDatas;

    public AppListAdapter(AbsListView listView, List<AppInfoBean> datas) {
        super(listView, datas);
        this.mDatas = datas;
    }

    @Override
    protected BaseHolder<AppInfoBean> getItemHolder(int position) {
        return new AppItemHolder();
    }

    /**
     * adapter中每个 item的点击事件
     */
    @Override
    protected void onNoramlItemClick(AdapterView<?> parent, View view,
            int position, long id) {
        // 跳转到应用详情页面
        Context context = UIUtils.getContext();
        Intent intent = new Intent(context, AppDetailActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putExtra(AppDetailActivity.KEY_PACKAGENAME,
                mDatas.get(position).packageName);
        context.startActivity(intent);
    }
}
-----------------------------------------------------------------------------------
=====================================================
public class AppItemHolder extends BaseHolder<AppInfoBean>
{
    // T ---> item 对应的数据
    // private TextView tv1;
    // private TextView tv2;

    @ViewInject(R.id.item_appinfo_iv_icon)
    private ImageView    mIvIcon;

    @ViewInject(R.id.item_appinfo_rb_stars)
    private RatingBar    mRbStar;

    @ViewInject(R.id.item_appinfo_tv_des)
    private TextView    mTvDes;

    @ViewInject(R.id.item_appinfo_tv_size)
    private TextView    mTvSize;

    @ViewInject(R.id.item_appinfo_tv_title)
    private TextView    mTvTitle;

    @Override
    protected View initView()
    {
        View view = View.inflate(UIUtils.getContext(), R.layout.item_app_info, null);

        // 初始化View
        // tv1 = (TextView) view.findViewById(R.id.tmp_tv_1);
        // tv2 = (TextView) view.findViewById(R.id.tmp_tv_2);

        // 注入
        ViewUtils.inject(this, view);

        return view;
    }

    @Override
    protected void refreshUI(AppInfoBean data)
    {
        // 给View设置数据
        // tv1.setText("头-" + data);
        // tv2.setText("内容-" + data);

        // 给View设置数据

        mTvDes.setText(data.des);
        mTvSize.setText(StringUtils.formatFileSize(data.size));
        mTvTitle.setText(data.name);

        mRbStar.setRating(data.stars);

        mIvIcon.setImageResource(R.drawable.ic_default);// 设置默认值

        // 需要去网络获取
        String uri = Constans.IMAGE_BASE_URL + data.iconUrl;
        BitmapHelper.display(mIvIcon, uri);
    }
}

===================================================================
public class HomeFragment extends BaseFragment
{
    private List<AppInfoBean>    mDatas;    // listView对应的数据
    private List<String>        mPictures;    // 轮播图对应的数据
    private HomeProtocol        mProtocol;

    @Override
    protected View onLoadSuccessView()
    {
        // TextView tv = new TextView(UIUtils.getContext());
        // tv.setText("首页");
        // return tv;

        ListView listView = ListViewFactory.getListView();

        // 创建轮播的holder
        HomePictureHolder holder = new HomePictureHolder();
        // 给listView添加头
        listView.addHeaderView(holder.getRootView());
        // 给holder设置数据
        holder.setData(mPictures);

        // 设置数据 -->adapter ---> list
        listView.setAdapter(new HomeAdapter(listView, mDatas));

        return listView;
    }

    // 此方法实在子线程中执行的
    @Override
    protected LoadedResult onLoadingData()
    {
        // ## 1. 随机数的模拟
        // LoadedResult[] results = new LoadedResult[] {
        // LoadedResult.ERROR, LoadedResult.SUCCESS
        // };
        // Random rdm = new Random();
        //
        // try
        // {
        // Thread.sleep(1000);
        // }
        // catch (InterruptedException e)
        // {
        // // TODO Auto-generated catch block
        // e.printStackTrace();
        // }
        // return results[rdm.nextInt(results.length)];

        // // ## 2.模拟假数据
        // mDatas = new ArrayList<String>();
        //
        // for (int i = 0; i < 50; i++)
        // {
        // mDatas.add(i + "");
        // }
        // return LoadedResult.SUCCESS;

        // ## 3.去网络加载数据
        // try
        // {
        // HttpUtils utils = new HttpUtils();
        // // method,url,header,params
        // String url = " http://10.0.2.2:8080/GooglePlayServer/home";
        // RequestParams params = new RequestParams();
        //
        // params.addQueryStringParameter("index", 0 + "");
        // ResponseStream stream = utils.sendSync(HttpMethod.GET, url, params);
        //
        // // 响应码
        // int statusCode = stream.getStatusCode();
        // if (200 == statusCode)
        // {
        // // 访问接口成功
        // // 获取json字符
        // String json = stream.readString();
        // // 解析json字符
        // Gson gson = new Gson();
        // HomeBean bean = gson.fromJson(json, HomeBean.class);
        //
        // // 判断bean是否为空
        // LoadedResult result = checkData(bean);
        // if (result != LoadedResult.SUCCESS) { return result; }
        //
        // result = checkData(bean.list);
        // if (result != LoadedResult.SUCCESS) { return result; }
        //
        // mDatas = bean.list;
        // mPictures = bean.picture;
        //
        // return result;
        // }
        // else
        // {
        // // 访问接口失败
        //
        // return LoadedResult.ERROR;
        // }
        //
        // }
        // catch (Exception e)
        // {
        // e.printStackTrace();
        // // 联网失败
        // return LoadedResult.ERROR;
        // }

        // ## 4.网络操作的简单抽取
        mProtocol = new HomeProtocol();

        try
        {
            HomeBean bean = mProtocol.loadData(0);

            // 判断bean是否为空
            LoadedResult result = checkData(bean);
            if (result != LoadedResult.SUCCESS) { return result; }

            result = checkData(bean.list);
            if (result != LoadedResult.SUCCESS) { return result; }

            mDatas = bean.list;
            mPictures = bean.picture;

            return result;

        }
        catch (Exception e)
        {
            e.printStackTrace();
            return LoadedResult.ERROR;
        }

    }

    class HomeAdapter extends AppListAdapter
    {

        public HomeAdapter(AbsListView listView, List<AppInfoBean> datas) {
            super(listView, datas);
            // TODO Auto-generated constructor stub
        }

        @Override
        protected List<AppInfoBean> onLoadMoreData() throws Exception
        {
            return loadMoreData(mDatas.size());
        }

    }

    private List<AppInfoBean> loadMoreData(int index) throws Exception
    {

        // HttpUtils utils = new HttpUtils();
        // // method,url,header,params
        // String url = " http://10.0.2.2:8080/GooglePlayServer/home";
        // RequestParams params = new RequestParams();
        //
        // params.addQueryStringParameter("index", index + "");
        // ResponseStream stream = utils.sendSync(HttpMethod.GET, url, params);
        //
        // // 响应码
        // int statusCode = stream.getStatusCode();
        // if (200 == statusCode)
        // {
        // // 访问接口成功
        // // 获取json字符
        // String json = stream.readString();
        // // 解析json字符
        // Gson gson = new Gson();
        // HomeBean bean = gson.fromJson(json, HomeBean.class);
        //
        // if (bean == null) { return null; }
        // return bean.list;
        // }
        // return null;

        HomeBean bean = mProtocol.loadData(index);
        if (bean == null) { return null; }
        return bean.list;
    }

}


1.SuperBaseAdapter
public abstract class SuperBaseAdapter<T> extends BaseAdapter implements OnItemClickListener
{
    private final static int    TYPE_LOAD_MORE        = 0;
    private final static int    TYPE_NORMAL_ITEM    = 1;

    private List<T>                mDatas;

    private LoadMoreHolder        mLoadMoreHolder;
    private LoadMoreTask        mLoadMoreTask;

    private AbsListView            mListView;

    public SuperBaseAdapter(AbsListView listView, List<T> datas) {
        this.mDatas = datas;

        this.mListView = listView;
        mListView.setOnItemClickListener(this);

    }

    @Override
    public int getCount()
    {
        if (mDatas != null) { return mDatas.size() + 1; }// 添加加载更多的item
        return 0;
    }

    @Override
    public Object getItem(int position)
    {
        if (mDatas != null) { return mDatas.get(position); }
        return null;
    }

    @Override
    public long getItemId(int position)
    {
        return position;
    }

    // adapter对应的item view的类型个数
    @Override
    public int getViewTypeCount()
    {
        return super.getViewTypeCount() + 1;// 添加加载更多的样式
    }

    // 当前position是什么type类型,返回的类型必须从0开始,而且需要累加
    @Override
    public int getItemViewType(int position)
    {
        if ((getCount() - 1) == position)
        {
            // 加载更多
            return TYPE_LOAD_MORE;
        }
        return getNormalItemViewType(position);
    }

    /**
     * 父类默认额外的item就只有一种,如果孩子需要多种,那么复写此方法
     * 
     * @param position
     * @return
     */
    protected int getNormalItemViewType(int position)
    {
        return TYPE_NORMAL_ITEM;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        BaseHolder holder = null;

        // ############### 1. 初始化item View #############################
        if (convertView == null)
        {
            if (getItemViewType(position) == TYPE_LOAD_MORE)
            {
                // 加载更多的holder
                holder = getLoadMoreHolder();
            }
            else
            {
                // 普通的holder

                // 没有复用
                // 1. 新建holder
                holder = getItemHolder(position);// 太具体化
                // 2. 加载视图
                // convertView = View.inflate(UIUtils.getContext(),
                // R.layout.item_tmp, null);// 太具体化
                // 通过holder 来提供 视图
            }
            convertView = holder.getRootView();

            // // 3.设置标记
            // convertView.setTag(holder);

            // // 4. 给holder初始化view
            // holder.tv1 = (TextView) convertView.findViewById(R.id.tmp_tv_1);
            // holder.tv2 = (TextView) convertView.findViewById(R.id.tmp_tv_2);
        }
        else
        {
            // 有复用
            holder = (BaseHolder) convertView.getTag();
        }
        // #########################################################

        // ############ 2. 给View设置数据 #############################
        // String data = mDatas.get(position);
        // // 给holder中的view设置数据
        // holder.tv1.setText("头-" + data);
        // holder.tv2.setText("内容-" + data);

        if (getItemViewType(position) == TYPE_LOAD_MORE)
        {
            // 给加载更多的holder添加数据

            if (hasLoadMore())
            {
                // 有加载更多的功能
                // 去网络加载数据,加载到 mDatas
                performLoadMoreData();
            }
            else
            {
                // 没有加载更多
                mLoadMoreHolder.setData(LoadMoreHolder.STATE_EMPTY);
            }

        }
        else
        {
            // 给普通holder添加数据

            T data = mDatas.get(position);
            // 给holder中的view设置数据
            holder.setData(data);
        }
        // #########################################################

        return convertView;
    }

    private void performLoadMoreData()
    {
        // 去网络加载数据,加载到 mDatas
        // 只允许一个加载更多的线程
        if (mLoadMoreTask != null)
        {
            // 正在加载
            return;
        }

        System.out.println("加载中......");

        // 设置状态为加载更多
        mLoadMoreHolder.setData(LoadMoreHolder.STATE_LOADING);

        mLoadMoreTask = new LoadMoreTask();
        ThreadManager.getLongPool().execute(mLoadMoreTask);
    }

    /**
     * 默认adapter具备加载更多的功能,如果子类不希望有,就复写此方法
     * 
     * @return
     */
    protected boolean hasLoadMore()
    {
        return true;
    }

    private LoadMoreHolder getLoadMoreHolder()
    {
        if (mLoadMoreHolder == null)
        {
            mLoadMoreHolder = new LoadMoreHolder();
        }

        return mLoadMoreHolder;
    }

    protected abstract BaseHolder<T> getItemHolder(int position);

    /**
     * 当加载更多时的回调,如果孩子有加载更多的功能,必须实现此方法
     * 
     * @return
     */
    protected List<T> onLoadMoreData() throws Exception
    {
        return null;
    }

    class LoadMoreTask implements Runnable
    {

        @Override
        public void run()
        {
            // 去网络加载数据,加载到 mDatas,UI更新
            List<T> mMoreDatas = null;
            int state = LoadMoreHolder.STATE_LOADING;
            try
            {
                mMoreDatas = onLoadMoreData();

                Thread.sleep(500);

                // 如果数据为空--> 服务器已经没数据了
                if (mMoreDatas == null || mMoreDatas.size() == 0)
                {
                    state = LoadMoreHolder.STATE_EMPTY;
                    return;
                }

                int size = mMoreDatas.size();

                // 如果数据不为空--> 小于一页的数据量,服务器已经没数据
                if (size < Constans.PAGER_SIZE)
                {
                    state = LoadMoreHolder.STATE_EMPTY;
                }
                else
                {
                    // 如果数据不为空 -->等于一页的数据量,服务器有可能有更多的数据
                    state = LoadMoreHolder.STATE_LOADING;
                }
            }
            catch (Exception e)
            {
                e.printStackTrace();

                state = LoadMoreHolder.STATE_ERROR;

            }

            final int currentState = state;
            final List<T> loadMoreDatas = mMoreDatas;
            UIUtils.post(new Runnable() {

                @Override
                public void run()
                {
                    // UI更新
                    // 更新加载更多
                    mLoadMoreHolder.setData(currentState);

                    if (currentState == LoadMoreHolder.STATE_ERROR)
                    {
                        // 如果产生异常
                        Toast.makeText(UIUtils.getContext(), "服务器异常", Toast.LENGTH_SHORT).show();
                    }

                    if (loadMoreDatas != null)
                    {
                        // 更新adapter
                        mDatas.addAll(loadMoreDatas);
                        // adapter更新
                        notifyDataSetChanged();
                    }
                }
            });

            // 执行完成
            mLoadMoreTask = null;
        }
    }

    /**
     * 如果孩子有item的点击事件,复写此方法即可
     * 
     * @param parent
     * @param view
     * @param position
     * @param id
     */
    protected void onNoramlItemClick(AdapterView<?> parent, View view, int position, long id)
    {

    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id)
    {
        // position 指的是listView的position(含头),不是adapter的position

        if (mListView instanceof ListView)
        {
            int count = ((ListView) mListView).getHeaderViewsCount();
            position = position - count;
        }

        if (getItemViewType(position) == TYPE_LOAD_MORE)
        {
            // 点击的是加载更多
            int currentState = mLoadMoreHolder.getCurrentState();
            if (currentState == LoadMoreHolder.STATE_ERROR)
            {
                // 去加载更多
                performLoadMoreData();
            }
        }
        else
        {
            // 点击的是普通的item
            onNoramlItemClick(parent, view, position, id);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值