• 模板代码


    模板代码 - 列表和下拉刷新

      手机应用一个常见的界面模式就是:顶部的ActionBar + TabStrip导航,中间的ListView,可以下拉刷新或者是底部的加载更多。通常ListView都需要是显示多种类型的条目。

    ActionBar-ViewPager-Fragment

    • 自定义一个带有ActionBar的主题:这样既可以获得ActionBar效果,又可以自己调整ActionBar的显示,如背景和字体等。下面主要是重新指定了tab_indicator。

      //在values/style.xml里:actionbar_tab_indicator的内容省略,官方文档有,很罗嗦。
      <style name="CustomActionBarTheme"
             parent="@android:style/Theme.Holo.Light">
          <item name="android:actionBarTabStyle">@style/MyActionBarTabs</item>
      </style>
      
      <!-- ActionBar tabs styles -->
      <style name="MyActionBarTabs"
             parent="@style/android:Widget.Holo.ActionBar.TabView">
          <!-- tab indicator -->
          <item name="android:background">@drawable/actionbar_tab_indicator</item>
      </style>
      
    • 让Activity继承FragmentActivity,定义一个继承自FragmentStatePagerAdapter的子类——MyPagerAdapter,活动布局中放置一个ViewPager填充整个界面。Activity.onCreate方法里为ActionBar设置属性:

      ActionBar actionBar = getActionBar();
      actionBar.setDisplayHomeAsUpEnabled(true);
      actionBar.setHomeButtonEnabled(true);
      
      //FragmentStatePagerAdapter的public Fragment getItem(int position)等相关方法正是配合ViewPager来完成
      //整个界面里切换Fragment的功能。它一直保持正在显示的,和左右(如果有)2个Fragment实例。
      
      //关联viewPager和FragmentStatePagerAdapter实例
      viewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
      
    • 在布局文件,ViewPager内放置android.support.v4.view.PagerTabStrip控件,这样可以显示ActionBar的tabs为特殊的样式,就是一直显示“左、中、右” 3个tab指示器,左右滑动ViewPager切换Fragment时,或者点击tab标签时左右滚动来显示更多其它的tab。(以后上图。。。)

    ListView显示多种类型的条目

      ListView支持显示多种类型的条目,并且可以同时复用不同条目的view。假设我们使用ListView显示一个下载应用的列表界面,在ListView的底部显示“加载更多”这样的按钮,那么就是让ListView同时显示2种类型的条目。

      ListView的getView方法正是我们为ListView提供要显示条目的地方,为了便于为普通的条目对应的view对象添加更多的控制,可以定义ViewHolder来组合View,并负责它的创建和状态控制。

    • 为显示的“应用信息”列表条目定义AppInfoViewHolder,它包含一个name和icon,布局文件item_appinfo是简单的ImageView和TextView,其ViewHolder定义如下:

      class AppInfoViewHolder{
          ImageView icon;
          TextView name;
          View itemView;
      
          public AppInfoViewHolder(){
              itemView = View.inflate(AppHelper.getContext(), R.layout.item_appinfo,null);
              icon = (ImageView)itemView.findViewById(R.id.appIcon);
              name = (TextView)itemView.findViewById(R.id.appName);
              //关联当前Holder和View
              itemView.setTag(this);
          }
      
          public void setViewData(AppInfo info){
              icon.setImageResource(info.getIconResId());
              name.setText(info.getName());
          }
      
          public View getView(){
              return itemView;
          }       
      }
      
    • 之后定义“加载更多”的LoadMoreViewHolder:

      public class LoadMoreViewHolder {   
      
          private View contentView;       
          private View loadMore;
          private View loading;
          private Button bt_loadMore;
      
          OnLoadMoreExecute loadMoreListener;
      
          public LoadMoreViewHolder{
              contentView = View.inflate(UIUtils.getContext(), R.layout.load_more, null);
              loadMore = contentView.findViewById(R.id.view_load_more);
              loading = contentView.findViewById(R.id.view_loading);
              bt_loadMore =  (Button) contentView.findViewById(R.id.bt_load_more);
              //关联当前Holder和View
              contentView.setTag(this);
              showLoadMore();
          }
      
          public interface OnLoadMoreExecute{
              void loadMore(LoadMoreHolder holder);
          }           
      
          //设置“加载更多”的业务逻辑
          public void setOnLoadMoreListener(OnLoadMoreExecute action){
              loadMoreListener = action;
              if(loadMoreListener != null ){                      
                  bt_loadMore.setOnClickListener(new OnClickListener() {
                      @Override
                      public void onClick(View v) {
                          loadMoreListener.loadMore(LoadMoreViewHolder.this);
                      }
                  });                             
              }   
          }       
      
          public void showLoading(){
              loading.setVisibility(View.VISIBLE);
              loadMore.setVisibility(View.INVISIBLE);
          }
      
          public void showLoadMore(){
              loadMore.setVisibility(View.VISIBLE);
              loading.setVisibility(View.INVISIBLE);
          }
      
          public View getView(){              
              return contentView;
          }
      }
      

        LoadMoreViewHolder提供加载更多加载中两种界面,当数据加载失败或者没有更多数据时,可以使用Toast进行界面提示,当然也可以动态改变“加载更多”按钮的显示文本。

        上面的LoadMoreViewHolder显示了使用ViewHolder来管理每个列表条目对应的View是非常方便的,这样可以让ListView的每个条目的创建、状态修改的代码都集中在一个类中,如果不是使用ViewHolder来组合View,那么对View状态的修改的代码就很容易分散地复杂起来。

    • ListView的多条目类型复用,主要是getView、getViewTypeCount、getItemViewType和getCount搭配使用。

      public class AppInfoAdapter extends BaseAdapter {
      
          List<AppInfo> infos;
          private final int ITEMTYPE_APP = 0;//条目类型对应的值范围是:0 ~ getViewTypeCount()-1
          private final int ITEMTYPE_MORE = 1;
      
          //显示的条目总数
          @Override
          public int getCount() {
              return infos.size() + 1;
          }
      
          //position处的条目的类型,条目类型对应的值范围是:0 ~ getViewTypeCount()-1
          @Override
          public int getItemViewType(int position) {
              if(position == infos.size()){
                  return ITEMTYPE_MORE;
              }else{
                  return ITEMTYPE_APP;
              }
          }
      
          //显示条目的类型数
          @Override
          public int getViewTypeCount() {
              return 2;
          }
      
          //根据position和convertView来创建或复用条目
          @Override
          public View getView(int position, View convertView, ViewGroup parent) {
              int viewType = getItemViewType(position);
              View view = null;
              switch (viewType) {
              case ITEMTYPE_APP:
                  AppInfoViewHolder appHolder = null;
                  if(convertView == null){
                      appHolder = new AppInfoViewHolder();
                  }else{
                      appHolder = (AppInfoViewHolder) view.getTag();
                  }
                  appHolder.setViewData(infos.get(position));
                  view = appHolder.getView();
                  break;
              case ITEMTYPE_MORE:
                  if(convertView == null){
                      LoadMoreViewHolder moreHolder = new LoadMoreViewHolder();
                      moreHolder.setOnLoadMoreListener(new OnLoadMoreExecute(){
                          @Override
                          public void loadMore(LoadMoreViewHolder holder){
                              asyncLoadMoreData(holder);
                          }
                      });
                      view = moreHolder.getView();
                  }else{
                      view = convertView;
                  }
                  break;
              }
              return view;
          }
      
          private void asyncLoadMoreData(LoadMoreViewHolder holder){
              holder.showLoading();
              new Thread(){
                  @Override
                  public void run() {
                      final List<AppInfo> newData = new AppInfoDao.getPageData(2);
                      UIHelper.runOnUiThread(new Runnable(){
                          @Override
                          public void run() {
                              if(newData == null){
                                  Toast.makeText(AppHelper.getContext(), "获取失败,稍后重试。", Toast.LENGTH_SHORT).show();
                              }else if(newData.size() == 0){
                                  Toast.makeText(AppHelper.getContext(), "没数据了,稍后重试。", Toast.LENGTH_SHORT).show();
                              }else{
                                  infos.addAll(newData);
                                  notifyDataSetChanged();
                              }
                              holder.showLoadMore();
                          }
                      });
                  }
              }.start();
          }
      }
      

      ListView可以添加多种类型的显示条目,常见的有顶部的轮播图片,顶部下拉刷新,以及底部的加载更多等等。借助ViewHolder来管理ListView要显示的条目,代码更容易集中,可以针对不同的条目设计不同的Holder类。

  • 相关阅读:
    i18n在4种常见环境下使用的方式
    vue-style里面设置变量
    扫码登录功能如何实现?一文搞懂主流的扫码登录技术原理
    Gradle编译Spring源码
    Spring学习总结(7)-AOP
    Docker安装Redis
    Jvm相关文章
    上传项目到Github
    Win10系统安装MySQL Workbench 8
    [转]HashMap 和 currentHashMap 总结
  • 原文地址:https://www.cnblogs.com/everhad/p/4827717.html
Copyright © 2020-2023  润新知