zoukankan      html  css  js  c++  java
  • ListView中不同类型view的实现

    首先创建请求队列,一个活动中只需要一个,因此放在Application中:

    public class MyApplication extends Application{
        private static  RequestQueue requestQueue;
    
        @Override
        public void onCreate() {
            super.onCreate();
             requestQueue = Volley.newRequestQueue(getApplicationContext());
    
        }
        public static RequestQueue getRequestQueue(){
            return requestQueue;
        }
    
    }

    注意:需要在清单文件中注册o~

      <application
            android:name=".MyApplication"
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">

    然后我们需要下载并解析json数据,这时候就需要自定义request继承request了,这里需要一个泛型参数,一般需要解析什么就设置什么,但是推荐使用泛型T,这样可以更方便为我们所使用了

    NewsBeanRequest:
    /**
     * Created by Administrator on 2016/9/27.
     */
    public class NewsBeanRequest extends Request<NewsBean> {
        private Response.Listener<NewsBean> listener;
    
        public NewsBeanRequest(int method, String url, Response.ErrorListener listener, Response.Listener<NewsBean> listener1) {
            super(method, url, listener);
            this.listener = listener1;
        }
    
        @Override
        protected Response<NewsBean> parseNetworkResponse(NetworkResponse response) {
            NewsBean newsBean = new NewsBean();
            Gson gson = new Gson();
            try {
                newsBean = gson.fromJson(new String(response.data, HttpHeaderParser.parseCharset(response.headers)),NewsBean.class);
            } catch (UnsupportedEncodingException e) {
                newsBean = gson.fromJson(new String(response.data),NewsBean.class);
            }
    
            return  Response.success(newsBean, HttpHeaderParser.parseCacheHeaders(response));
        }
    
        @Override
        protected void deliverResponse(NewsBean response) {
            listener.onResponse(response);
        }
    }

    上面代码分为三部分:

    0.定义构造方法,传入请求网络需要的参数,通过父类去请求网络

    1.解析网络请求的响应结果,将 字节数组类型的数据转换成自己想要的 T (通常是java bean数据模型)

    2.deliverResponse(T response) 分发响应结果(处理监听)调用请求成功的监听器

    接下来就是主程序了,

    main:

    public class MainActivity extends AppCompatActivity {
    
        private ListView listview;
        private RequestQueue requestQueue;
        private static final String URL = "http://ikft.house.qq.com/index.php?guid=866500021200250&devua=appkft_1080_1920_XiaomiMI4LTE_1.8.3_Android19&devid=866500021200250&appname=QQHouse&mod=appkft&reqnum=&pageflag=&act=newslist&channel=71&buttonmore=&cityid=1";
        private List<NewsBean.DataBean> dataList = new ArrayList<>();
        private NewsListAdapter newsListAdapter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            listview = (ListView) findViewById(R.id.listview);
            //创建适配器
           newsListAdapter = new NewsListAdapter(this,dataList);
            //设置适配器
            listview.setAdapter(newsListAdapter);
            //1,创建RequestQueue
             requestQueue = MyApplication.getRequestQueue();
            //2.自定义对象请求
            NewsBeanRequest newsBeanRequest = new NewsBeanRequest(Request.Method.GET, URL, new Response.ErrorListener() {
                @Override 
                public void onErrorResponse(VolleyError error) {
                    Log.i("tag", "下载数据失败");
                }
            }, new Response.Listener<NewsBean>() {
                @Override
                public void onResponse(NewsBean response) {
                    //返回的数据为下载并解析后的newsBean对象
                    newsListAdapter.addData(response.getData());
                }
            });
            //设置标记
            newsBeanRequest.setTag(URL);
            //3.添加到请求队列中
            requestQueue.add(newsBeanRequest);
    
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            //4.取消该标记对应的请求
            requestQueue.cancelAll(URL);
        }
    }

    一般的从网上获取数据就是上面这四步了,

    给请求设置一个tag是为了请求队列取消请求的时候,可以通过tag来取消tag对应的请求

    还有一种方式可以取消:newsBeanrequest.canel();//取消自己

    一般在活动销毁的时候将请求也取消

    接下来就是适配器中对数据进行设置了:

    class NewsListAdapter extends BaseAdapter {
        private Context context;
        private List<NewsBean.DataBean>dataList;
    
        public NewsListAdapter(Context context, List<NewsBean.DataBean> dataList) {
            this.context = context;
            this.dataList = dataList;
        }
    
        /**
         *添加数据
         * @param dataList
         */
        public void addData(List<NewsBean.DataBean> dataList){
            this.dataList.addAll(dataList);
            notifyDataSetChanged();
        }
        @Override
        public int getCount() {
            return dataList.size();
        }
    
        @Override
        public Object getItem(int position) {
            return dataList.get(position);
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        /* 获得当前adapter中view的种类的数量*/
        @Override
        public int getViewTypeCount() {
            return 2;
        }
        /*根据position来获得当前的要显示的item的view类型*/
        @Override
        public int getItemViewType(int position) {
            return new Integer(dataList.get(position).getType());
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            //得到当前复用的view的类型
    //        int type = Integer.parseInt(dataList.get(position).getType());
            //得打NewsBean.DataBean中的参数int type
            int type = getItemViewType(position);
            NewsBean.DataBean dataBean = dataList.get(position);
            //1.创建ImageLoader对象
            ImageLoader imageLoader = new ImageLoader(MyApplication.getRequestQueue(),new MyImageCache());
            ViewHolder1 viewHolder1 = null;
            ViewHolder2 viewHolder2 = null;
            switch (type){
                case 0:
                    if(convertView == null){
                        convertView = LayoutInflater.from(context).inflate(R.layout.listview_item_news_1,parent,false);
                        viewHolder1 = new ViewHolder1(convertView);
                        convertView.setTag(viewHolder1);
                    }else{
                        viewHolder1 = (ViewHolder1)convertView.getTag();
                    }
                    viewHolder1.tvSummary.setText(dataBean.getSummary());
                    viewHolder1.tvTitle.setText(dataBean.getTitle());
    
                    //2.声明监听
                    ImageLoader.ImageListener listener = ImageLoader.getImageListener(viewHolder1.imgGroupthumbnail, R.mipmap.ic_launcher, R.mipmap.ic_launcher);
                    //3.加载图片
                    imageLoader.get(dataBean.getGroupthumbnail(),listener);
                    break;
                case 1:
                    if(convertView ==null){
                        convertView = View.inflate(context,R.layout.listview_item_news_2,null);
                        viewHolder2 = new ViewHolder2(convertView);
                        convertView.setTag(viewHolder2);
                    }else{
                        viewHolder2 = (ViewHolder2)convertView.getTag();
                    }
                    ImageLoader.ImageListener listener1 = ImageLoader.getImageListener(viewHolder2.imgGroupthumbnail, R.mipmap.ic_launcher, R.mipmap.ic_launcher);
                    imageLoader.get(dataBean.getGroupthumbnail(),listener1);
                    break;
            }
    
            return convertView;
        }
        class ViewHolder1 {
            public ImageView imgGroupthumbnail;
            public TextView tvTitle;
            public TextView tvSummary;
    
            public ViewHolder1(View view) {
                this.imgGroupthumbnail = (ImageView) view.findViewById(R.id.img_groupthumbnail);
                this.tvTitle = (TextView) view.findViewById(R.id.tv_title);
                this.tvSummary = (TextView) view.findViewById(R.id.tv_summary);
            }
        }
    
        class ViewHolder2 {
            public ImageView imgGroupthumbnail;
    
            public ViewHolder2(View view) {
                this.imgGroupthumbnail = (ImageView) view.findViewById(R.id.img_groupthumbnail);
    
            }
        }
        class MyImageCache implements ImageLoader.ImageCache{
            private LruCache<String,Bitmap> lruCache;
    
            public MyImageCache() {
                lruCache = new LruCache<String,Bitmap>((int) (Runtime.getRuntime().maxMemory()/8)){
                    @Override
                    protected int sizeOf(String key, Bitmap value) {
                        return value.getByteCount();
                    }
                };
            }
    
            @Override
            public Bitmap getBitmap(String url) {
                return lruCache.get(url);
            }
    
            @Override
            public void putBitmap(String url, Bitmap bitmap) {
                lruCache.put(url,bitmap);
            }
        }
    }

    法解析:

    addData:自定义的对外暴露的添加数据的方法,当数据发生改变的时候调用,添加数据
    重写适配器中的两个方法,
    getViewTypeCount()//得到类型的个数
    getItemViewType()//得到当前复用view的类型

    在adapter的getView方法中,得到当前显示view的type并判断,然后根据判断的type类型对该类型对应的view布局来进行操作

    ,如果可复用的布局为空,首先得到当前需要显示的布局,布局通过布局加载器来加载布局,并传入自定义类ViewHolder中,而viewholder的作用是装载控件的,我们可以通过id找到布局中对应的控件,最后,该viewHolder设置为convertview的一个标记,然后我们就可以通过dataList.get(position)得到当前item的数据,并设置到控件上了,当然,如果当前可复用的view不为空,直接通过getTag()方法就可以得到viewHolderl ,操作同上

    我们下载图片是通过imageLoader来实现的

    ImageLoader是一个图片加载器,可以设置缓存,

    首先创建一个ImageLoader对象,里面传递两个参数,

    第一个参数是请求队列,一般通过Volley.newRequestQueue来获取,但是一般一个activity中有一个就足够,因此我设置到了MyApplication中.

    第二个参数是图片缓存的实现类对象,里面实现了两个方法,分别是对图片的取和存,不过得先创建一个内存缓存,我将他的实现放在了构造方法里面,这样在创建该对象的时候就直接创建了,创建对象需要传入一个参数,该参数指定缓存的大小,这里我设置的是总空间大小的1/8,然后重写sizeOf方法返回每张图片的大小,当构造方法中设置的是一个固定的数值的时候,返回参数设置为1

    然后为图片设置监听器:监听回调的数据

    参数1: 需要展示图片的imageview   , 2.默认图片  3.错误图片

    最后ImageLoader加载图片

    放入请求队列
    参数1:path 网络地址 参数2: 请求成功的监听,请求成功会回调listener
    imageLoader.get(path,imagelistener);

    现在图片也下载完成了,我们可以看到效果:

     

  • 相关阅读:
    opencv学习之米粒分割 #201906121549
    opencv学习之hsv通道分解 #201906101704
    opencv学习之图像滤波预处理 #201906101646
    opencv学习之addWeighted图片打水印 #201906061030
    alpha channel
    rm git commit history
    git 使用学习
    排序算法的c++实现
    leetcode 246 中心对称数问题
    大数打印问题
  • 原文地址:https://www.cnblogs.com/fangg/p/5914798.html
Copyright © 2011-2022 走看看