当前位置: 首页 > news >正文

Android Adapter

为什么80%的码农都做不了架构师?>>>   hot3.png


Adapter是用来帮助填充数据的中间桥梁,比如通过它将数据填充到ListView, GridView, Gallery.而android 提供了几种Adapter:ArrayAdapter, BaseAdapter, CursorAdapter, HeaderViewListAdapter, ListAdapter, ResourceCursorAdapter, SimpleAdapter, SimpleCursorAdapter, SpinnerAdapter, WrapperListAdapter.
根据数据来源形式的不同可以选择不同的Adapter,比如数据来源于一个Arraylist 就使用BaseAdapter,SimpleAdapter,而数据来源于通过查询数据库获得Cursor那就使用SimpleCursorAdapter.
使用simpleadapter的例子:

主布局文件
<!-- main.xml-->
<? xml version ="1.0" encoding ="utf-8" ?>
< LinearLayout xmlns:android ="http://schemas.android.com/apk/res/android"
         android:orientation ="vertical"
         android:layout_width ="fill_parent"
         android:layout_height ="fill_parent"
         >
         < RelativeLayout
       android:layout_width ="wrap_content"
       android:layout_height ="wrap_content"
         >
         < Spinner
                 android:id ="@+id/subway_lines"
                 android:layout_width ="fill_parent"
                 android:layout_height ="wrap_content" >
         </ Spinner >
         < TextView
             android:layout_width ="fill_parent"
             android:layout_height ="wrap_content"
             android:layout_below ="@id/subway_lines"
             android:layout_alignLeft ="@id/subway_lines"
             android:id ="@+id/select_line"
         />
     </ RelativeLayout >
     < ListView
     android:layout_width ="fill_parent"
     android:layout_height ="fill_parent"
     android:id ="@+id/station_listView"
     />
</ LinearLayout >

然后是ListView布局
<!-- stationitem.xml-->
<? xml version ="1.0" encoding ="utf-8" ?>
< RelativeLayout
     xmlns:android ="http://schemas.android.com/apk/res/android"
     android:layout_width ="fill_parent"
     android:layout_height ="fill_parent" >
     < TextView
         android:layout_width ="200px"
         android:layout_height ="fill_parent"
         android:textSize ="20px"
         android:gravity ="center_horizontal"
         android:id ="@+id/station_name"
     />
     < TextView
         android:layout_width ="200px"
         android:layout_height ="fill_parent"
         android:layout_toRightOf ="@id/station_name"
         android:textSize ="20px"
         android:layout_alignTop ="@id/station_name"
         android:id ="@+id/station_info"
     />
</ RelativeLayout >

接下来是Activity
import java.util.ArrayList;

public class SubwayActivity extends Activity {

         private static final String TAG = "SubwayActivity";
         private SubwayService subwayService;
         private TextView selectLine;
         private Spinner subwayLines;
         private ArrayAdapter<String> linesAdapter;
         private List<String> linesNames;
         private ListView stationListView;
         private SimpleAdapter stationsAdapter;

        @Override
         public void onCreate(Bundle savedInstanceState) {
                 super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    stationListView = (ListView) findViewById(R.id.station_listView);
    subwayService = new SubwayService( this);

     //初始化数据
//    subwayService.init();

    List<SubwayLine> listLines = subwayService.getLineScrollData();
    linesNames = new ArrayList<String>();
     for (SubwayLine subwayLine : listLines) {
      linesNames.add(subwayLine.getLineName());
    }
     // 第一步:添加一个下拉列表项的list,这里添加的项就是下拉列表的菜单项
    selectLine = (TextView) findViewById(R.id.select_line);
    subwayLines = (Spinner) findViewById(R.id.subway_lines);
     // 第二步:为下拉列表定义一个适配器,这里就用到里前面定义的list。
    linesAdapter = new ArrayAdapter<String>( this, android.R.layout.simple_spinner_item,linesNames);
     // 第三步:为适配器设置下拉列表下拉时的菜单样式。
    linesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
     // 第四步:将适配器添加到下拉列表上
    subwayLines.setAdapter(linesAdapter);
     //第五步:为下拉列表设置各种事件的响应,这个事响应菜单被选中
    subwayLines.setOnItemSelectedListener(selectedListener);
     /*下拉菜单弹出的内容选项触屏事件处理*/
    subwayLines.setOnTouchListener(onTouchListener);
     /*下拉菜单弹出的内容选项焦点改变事件处理*/
    subwayLines.setOnFocusChangeListener(onFocusChangeListener);
        }

         /**
         * 为下拉列表设置各种事件的响应,这个事响应菜单被选中
         */
         private OnItemSelectedListener selectedListener =     new Spinner.OnItemSelectedListener(){
          @SuppressWarnings( "unchecked")
                 public void onItemSelected(AdapterView arg0, View arg1, int arg2, long arg3) {
            String lineName = linesAdapter.getItem(arg2);
            SubwayLine line = subwayService.findLine(lineName);
             /*根据lineId查询出stations*/
            List<SubwayStation> stations = subwayService.getStationLineScrollData(line.getLineId());
             /*把stations的属性值放到List<HashMap<String, String>>中*/
            List<HashMap<String, String>> data = new    ArrayList<HashMap<String, String>>();
                         for (SubwayStation station : stations) {
                          HashMap<String, String> map = new HashMap<String, String>();
                           if(station.getIsChange() == 1){
                            map.put( "stationName", station.getStationName());
                            List<SubwayStation> changeStations = subwayService.getChangeStationExceptThis(station.getStationName(), line.getLineId());
                            StringBuilder builder = new StringBuilder();
                            builder.append( "换乘 ");
                             if(changeStations != null && changeStations.size() > 0){
                               for (SubwayStation changeStation : changeStations) {
                                SubwayLine changeLine = subwayService.findLine(changeStation.getLineId());
                                      builder.append(changeLine.getLineName()).append( ",");
                  }
                              builder.deleteCharAt(builder.length()-1);
                            }
                                  map.put( "stationInfo",builder.toString());
                          } else{
                            map.put( "stationName", station.getStationName());
                                  map.put( "stationInfo", station.getStationInfo());
                          }
                                data.add(map);
            }
                         /*设置stationsAdapter适配器*/
      stationsAdapter = new SimpleAdapter(
          SubwayActivity. this,
          data,
          R.layout.stationitem,
           new String[] { "stationName", "stationInfo" },
           new int[] { R.id.station_name, R.id.station_info });
      stationListView.setAdapter(stationsAdapter);

                         /* 将所选mySpinner 的值带入myTextView 中*/
                  selectLine.setText( "以下是:"+ lineName + " 车站列表...");
                         /* 将mySpinner 显示*/
                        arg0.setVisibility(View.VISIBLE);
                }
                @SuppressWarnings( "unchecked")
                 public void onNothingSelected(AdapterView arg0) {
                  selectLine.setText("");
                        arg0.setVisibility(View.VISIBLE);
                }
        };

         /**
         * 下拉菜单弹出的内容选项触屏事件处理
         */
         private OnTouchListener onTouchListener = new Spinner.OnTouchListener(){
                 public boolean onTouch(View v, MotionEvent event) {
                         /* 将mySpinner 隐藏,不隐藏也可以,看自己爱好*/
//                        v.setVisibility(View.INVISIBLE);
                         return false;
                }
        };

         /**
         * 下拉菜单弹出的内容选项焦点改变事件处理
         */
         private OnFocusChangeListener onFocusChangeListener = new Spinner.OnFocusChangeListener(){
     public void onFocusChange(View v, boolean hasFocus) {
      v.setVisibility(View.VISIBLE);
    }
  };
}

其中,核心的是
/*设置stationsAdapter适配器*/
            stationsAdapter = new SimpleAdapter(
                    SubwayActivity. this,
                    data,
                    R.layout.stationitem,
                     new String[] { "stationName", "stationInfo" },
                     new int[] { R.id.station_name, R.id.station_info });
            stationListView.setAdapter(stationsAdapter);

===========================================================
以上是简单的使用adapter的方法,一般情况下这样就够用了.接下来是自定义adapter.

继承BaseAdapter,重写四个方法.
public class WeatherAdapter extends BaseAdapter {

         private Context context;
         private List<Weather> weatherList;         //这就是adapter关联的List,用来存储数据.还记的ArrayList

         public WeatherAdapter(Context context, List<Weather> weatherList ) {
                 this.context = context;
                 this.weatherList = weatherList;
        }

         public int getCount() {
                 return weatherList.size();
        }

         public Object getItem( int position) {
                 return weatherList.get(position);
        }

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

         public View getView( int position, View convertView, ViewGroup parent) {
                Weather weather = weatherList.get(position);
                 return new WeatherAdapterView( this.context, weather );
        }

}

自定义的View
class WeatherAdapterView extends LinearLayout {
                 public static final String LOG_TAG = "WeatherAdapterView";

                 public WeatherAdapterView(Context context,
                                                                Weather weather ) {
                         super( context );

                         this.setOrientation(HORIZONTAL);
                        LinearLayout.LayoutParams cityParams =
                                 new LinearLayout.LayoutParams(100, LayoutParams.WRAP_CONTENT);
                        cityParams.setMargins(1, 1, 1, 1);

                        TextView cityControl = new TextView( context );
                        cityControl.setText( weather.getCity() );
                        addView( cityControl, cityParams);

                        LinearLayout.LayoutParams temperatureParams =
                                 new LinearLayout.LayoutParams(20, LayoutParams.WRAP_CONTENT);
                        temperatureParams.setMargins(1, 1, 1, 1);

                        TextView temperatureControl = new TextView(context);
                        temperatureControl.setText( Integer.toString( weather.temperature ) );
                        addView( temperatureControl, temperatureParams);

                        LinearLayout.LayoutParams skyParams =
                                 new LinearLayout.LayoutParams(25, LayoutParams.WRAP_CONTENT);

                        ImageView skyControl = new ImageView( context );
                        Log.d( LOG_TAG, weather.getCity()+ " -> "+weather.sky );
                        skyControl.setImageResource( weather.getSkyResource() );
                        addView( skyControl, skyParams );
                }
}

最后在Activity中使用
public class CustomAdapterActivity extends ListActivity
{
        @Override
         public void onCreate(Bundle savedInstanceState)
        {
                 super.onCreate(savedInstanceState);
                setContentView(R.layout.main);
                ArrayList<Weather> weatherList = new ArrayList<Weather>();
                Weather w = new Weather( "London", 17, Weather.OVERCAST );
                weatherList.add( w );
                w = new Weather( "Paris", 22, Weather.OVERCAST );
                weatherList.add( w );
                w = new Weather( "Athens", 29, Weather.SUNNY );
                weatherList.add( w );
                w = new Weather( "Stockholm", 12, Weather.RAIN );
                weatherList.add( w );
                WeatherAdapter weatherAdapter = new WeatherAdapter(
                                 this,
                                weatherList );
                setListAdapter( weatherAdapter );
        }
}


===========================================================
再就是Adapter的优化,一个广为流传的 ViewHolder、ViewCache办法:

public View getView( int position, View convertView, ViewGroup parent) {

  ViewHolder holder;
   if (convertView == null) {
    holder = new ViewHolder();
    convertView = inflater.inflate(R.layout.topic_list, null);
    holder.title = (TextView) convertView.findViewById(R.id.title);
    convertView.setTag(holder);
  } else {
    holder = (ViewHolder) convertView.getTag();
  }
}

public class ViewHolder {
   public TextView getTitle() {
     if (title == null) {
      title = (TextView) baseView.findViewById(R.id.title);
    }
     return title;
  }
}


或者使用HashMap做缓存的方法:

HashMap<Integer, View> m = new HashMap<Integer, View>();

public View getView( int position, View view, ViewGroup parent) {

  View convertView = m.get(position);
   if (convertView != null) {
     return convertView;
  } else {
    convertView = inflater.inflate(R.layout.topic_list, null);
    TextView title = (TextView) convertView.findViewById(R.id.title);
    m.put(position, convertView);
  }
}




本文出自 “wIsper 把技术做成艺术” 博客,请务必保留此出处http://lichen.blog.51cto.com/697816/492200

转载于:https://my.oschina.net/lichen/blog/264921

相关文章:

  • ognl表达式
  • 直播APP关于后期运营你知道多少?
  • 【新手向】vim快捷注释与删除操作
  • Maven搭建SpringMVC+Mybatis项目详解
  • Access restriction: The method createJPEGEncoder(OutputStream) from the type JPEGCodec is not access
  • 路由器简单的基础实验
  • Android(java)学习笔记18:单例模式
  • 感受
  • 黑马程序员--C语言中的枚举
  • 父窗口中得知window.open()出的子窗口关闭事件
  • CYQ.Data 快速开发之UI(赋值、取值、绑定)原理
  • 码医自学法V2.2(附名老中医)
  • MVC 根据模板动态生成静态页面
  • 剑指OFFER之变态跳台阶(九度OJ1389)
  • Markdown 学习笔记
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • Android开发 - 掌握ConstraintLayout(四)创建基本约束
  • conda常用的命令
  • JavaScript异步流程控制的前世今生
  • JWT究竟是什么呢?
  • nodejs调试方法
  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
  • React Transition Group -- Transition 组件
  • Redis学习笔记 - pipline(流水线、管道)
  • Webpack 4x 之路 ( 四 )
  • XForms - 更强大的Form
  • 初识 webpack
  • 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  • 如何抓住下一波零售风口?看RPA玩转零售自动化
  • 通过几道题目学习二叉搜索树
  • 自定义函数
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • JavaScript 新语法详解:Class 的私有属性与私有方法 ...
  • #{} 和 ${}区别
  • #git 撤消对文件的更改
  • (14)Hive调优——合并小文件
  • (C)一些题4
  • (Python) SOAP Web Service (HTTP POST)
  • (rabbitmq的高级特性)消息可靠性
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (附源码)php投票系统 毕业设计 121500
  • (接口封装)
  • (论文阅读23/100)Hierarchical Convolutional Features for Visual Tracking
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (十一)图像的罗伯特梯度锐化
  • (一)插入排序
  • (转)Sublime Text3配置Lua运行环境
  • .NET Core WebAPI中封装Swagger配置
  • .NET 指南:抽象化实现的基类
  • .NET单元测试
  • .net的socket示例
  • .NET开源项目介绍及资源推荐:数据持久层 (微软MVP写作)
  • [100天算法】-目标和(day 79)
  • [23] 4K4D: Real-Time 4D View Synthesis at 4K Resolution