zoukankan      html  css  js  c++  java
  • 实现顶部轮播,下部listview经典布局的两种方式

    开头:

    在做android开发的时候,我们经常会遇到这样的布局,上面是一个图片轮播图,下面是一些列表的项目。很多新闻app,视频类app都采用这样的布局。起初的时候

    由于没有很多参考,我自己想到了一种实现方式,就是用scrollview作为外面最大的布局,然后里面嵌套viewpager和listview,但是我现在非常不推荐这种方式,一方面由于这种方式

    需要将listview完全展开,缺少了getview函数中应该有的复用与优化。而且结构嵌套复杂。经过一番查找与学习,学习到两种比较规范或者结构比较清晰的实现方式,那么下面,我来分别介绍

    一下这两种方式。

     转载请注明出处   http://www.cnblogs.com/gaoteng/p/4162749.html   www.gaotenglife.com

    方法一:listview的addheadview方法

    首先我们新建一个布局文件,存放listview,如下

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
     
        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="16dp"
            android:text="first" />
        <ListView
            android:id="@+id/list_view_first"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/textView1"
            />
    </RelativeLayout>

      布局很简单,里面就主要有一个listview。

     

    然后顶部的轮播图,我们采用viewpager的方式去实现。同样新建一个布局,里面存放viewpager

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?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="100dp"
        android:orientation="vertical" >
         
    <android.support.v4.view.ViewPager
        android:id="@+id/headviewpager"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        />
    </LinearLayout>

     通过上面两步,我们已经建立好了用到的布局文件,很简单。

     

    那么接下来,viewpager需要一个adapter来填充数据,这里我们的数据,就是一些图片,让viewpager去展示。

    我们再新建一个自己的viewpageradapter,这个adapger在后面的另一种实现方式中也会用到,所以,单独建立一个文件存放。

     

    下面是代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    /**
     *
     * @author xuelang www.gaotenglife.com
     *
     */
    public class ViewPageAdapter extends PagerAdapter
        {
     
            List<ImageView> list = null;//我们用一个list存放所有的imageview
            public ViewPageAdapter (List<ImageView> _list)
            {
                list = _list;
            }
             
            @Override
            public void destroyItem(View container, int position, Object object) {
                // TODO Auto-generated method stub
                ((ViewPager)container).removeView(list.get(position));
                 
            }
     
            @Override
            public Object instantiateItem(View container, int position) {
                // TODO Auto-generated method stub
                ((ViewPager) container).addView(list.get(position));
                return list.get(position);
            }
     
            @Override
            public int getCount() {
                // TODO Auto-generated method stub
                return list.size();//返回数据的个数
            }
     
            @Override
            public boolean isViewFromObject(View arg0, Object arg1) {
                // TODO Auto-generated method stub
                return (arg0 == arg1);//这句话,比较重要,加上之后才能正确显示
            }
             
    }

      上面的代码很简单,是一个pageadapter的标准用法。这样我们基本上所有的准备工作已经完成了,最后一步,就是我们把viewpager通过listview的addheadview方式加入到listview的头上。

     

    下面便是acitivity中的主要代码(在文章的结尾,我会附加源代码的下载地址,有需要的可以下载详细看)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    private void initHeadView()
        {
            listview = (ListView)this.findViewById(R.id.list_view_first);  
            View view = LayoutInflater.from(this).inflate(R.layout.head_viewpager, null);
            ViewPager viewpager = (ViewPager)view.findViewById(R.id.headviewpager);    
            List<ImageView> listtemp = new ArrayList<ImageView>();
            for(int i = 0;i<4;i++)
            {
                ImageView img = new ImageView(this);
                img.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,100));
                img.setScaleType(ScaleType.FIT_XY);
                img.setBackgroundResource(R.drawable.ic_launcher);
                listtemp.add(img);
            }      
            ViewPageAdapter viewadapter = new ViewPageAdapter(listtemp);       
            listview.addHeaderView(view);
            listview.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,data));
            viewpager.setAdapter(viewadapter);
        }

      

     简单解释一下上面的内容:

    1
    LayoutInflater.from(this).inflate(R.layout.head_viewpager, null);<br>这句话将我们之前建立好的布局文件载入进来<br><br>然后通过for循环初始化imageview的list
    1
    for(int i = 0;i<4;i++)<br>....<br><br> 最重要的就是这句话
    1
    listview.addHeaderView(view);<br><br>将初始化好的view添加到head上面。至此我们的第一种方法,就已经完成,是不是很简单。<br><br><br>

     方法二:viewpager作为listview的一个item

     

      这种方式是我受到别的文章的启发,一个listview可以指定它每一个item为不同的布局类型,从而实现listview的多元化,那么我们同样可以利用这个方法。

    把listview的第一项初始化为viewpager,这样不也就实现了顶部时viewpager的效果了嘛。说干就干,代码继续码起来。

     

    在这种方式中,最主要的内容部分就在listview的adapter中。所以我也就主要介绍这一个adapter,我相信,看懂了这个adapter,那么其他部分,自然很容易理解了。

    在官方api中提供了下面这两个方法,这也是今天实现这个功能主要的两个方法。

    getViewTypeCount //用来返回在这个listview中有几种不同的item类型

    getItemViewType //用来返回某个具体位置上面的item的类型()

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @Override
            public int getItemViewType(int position) {
                // TODO Auto-generated method stub
                return position>0?0:1;
            }
     
            @Override
            public int getViewTypeCount() {
                // TODO Auto-generated method stub
                return 2;
            }

      由于我们只做一个简单演示,所以就分为两种类型,一种是viewpager类型的item,另一种是不同类型的item,所以当position大于0,也就是我们的普通类型,position等于0,就是第一项,也就是viewpager。

     

    接下来便是这个功能最最重要的一个函数getview,因为我们将在这个函数中做所有的显示工作。

     

    我们先把代码附上,然后详细介绍。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
             View view = null;
             if(getItemViewType(position) == 0)//
             {
                ViewHolder holder = null
                 
                 if(convertView==null)
                 {
                     
                         view = m_inflater.inflate(R.layout.list_item, null);
                         holder = new ViewHolder();
                         holder.textView = (TextView)view.findViewById(R.id.list_item);
                         view.setTag(holder);
                 }             
                 else
                 {
                     view  = convertView;
                     holder = (ViewHolder)view.getTag();
                 }
                 holder.textView.setText(position+"");
            }
            else if(getItemViewType(position) == 1)//如果是顶部viewpager
             {
                ViewPagerHolder holder = null
                 if(convertView==null)
                 {
                     view = m_inflater.inflate(R.layout.head_viewpager, null);
                     holder = new ViewPagerHolder();
                     holder.viewPager = (ViewPager)view.findViewById(R.id.headviewpager);
                      
                      
                     List<ImageView> listtemp = new ArrayList<ImageView>();
                     for(int i = 0;i<4;i++)
                     {
                        ImageView img = new ImageView(SecondActivity.this);
                        img.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,100));
                        img.setScaleType(ScaleType.FIT_XY);
                        img.setBackgroundResource(R.drawable.ic_launcher);
                        listtemp.add(img);
                     }
                         
                    ViewPageAdapter viewadapter = new ViewPageAdapter(listtemp);
                    holder.viewPager.setAdapter(viewadapter);
     
                     view.setTag(holder);
                 }
                 else
                 {
                     view  = convertView;
                     holder = (ViewPagerHolder)view.getTag();
                 }              
             }
             
            return view;
        }
     
    }

      

     

    下面我来详细说明一下上面的函数。其实基本的骨架大家应该都能看懂。使用了listview复用的概念。

    1
    if(getItemViewType(position) == 1)

    通过这个判断目前需要显示的view是哪种类型。那么这里如果是1,就是我们的viewpager项,

    然后再判断convertView是否为空,来决定是否复用。

     

    如果为空,说明在内存中没有保留过,于是通过LayoutInflate创建view,同时我们创建了一个

    1
    holder = new ViewPagerHolder();

    缓冲,用来保存之前创建好的布局,以便下次使用。

     

    然后创建好viewpager的数据List<ImageView> data,使用前面的ViewPageAdapter,将数据与viewpager绑定,然后用settag的方式,把holder数据,保存到view里面。

     

    当判断convertview不为空的时候,我们从convertview中取出tag,转换为holder,然后就又得到了viewpager对象了。

     

    这是if(getItemViewType(position) == 1)的情况。

    那么if(getItemViewType(position) == 0)的情况就更简单了,基本上和这类似。

     

    也是复用了convertview,然后通过holder的方式,将view对象保存起来,不用下一次通过findviewbyid的方式来查找了,提高了效率。

      转载请注明出处   http://www.cnblogs.com/gaoteng/p/4162749.html   www.gaotenglife.com

     

    下面附上源码下载地址

    csdn资源

    http://download.csdn.net/detail/gaotengguojianhong/8308407

     

    github资源

    https://github.com/langxuelang/ListViewDemo

  • 相关阅读:
    9月7日总结
    Arbitrage题解
    杀蚂蚁题解
    8月11日总结
    8月10总结
    PHP 关于获取客户端ip的方法
    PHP内置函数大全
    PHP header函数设置http头
    获取两个日期之间的全部的日期数据(包括两个日期)
    根据周日获取这周的周日到周六的日期(周日为这周的第一天)
  • 原文地址:https://www.cnblogs.com/xieping/p/4784529.html
Copyright © 2011-2022 走看看