Android之ListView&ViewPager模拟新闻界面

模拟新闻 APP 的界面

 

1)写 ListView 之前先写布局:

 这里有两种 Item 的布局:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="100dp"
 5     android:padding="10dp">
 6 
 7 
 8     <ImageView
 9         android:layout_width="100dp"
10         android:layout_height="60dp"
11         android:id="@+id/imageView"
12         android:background="@mipmap/ic_launcher"
13         android:layout_centerVertical="true"
14         android:layout_alignParentRight="true" />
15 
16     <TextView
17         android:layout_width="wrap_content"
18         android:layout_height="wrap_content"
19         android:text="New Text"
20         android:id="@+id/tv_title"
21         android:maxLines="3"
22         android:layout_marginRight="10dp"
23         android:layout_alignParentTop="true"
24         android:layout_alignParentLeft="true"
25         android:layout_toLeftOf="@+id/imageView" />
26 
27     <TextView
28         android:layout_width="wrap_content"
29         android:layout_height="wrap_content"
30         android:textAppearance="?android:attr/textAppearanceSmall"
31         android:text="Small Text"
32         android:id="@+id/tv_time"
33         android:layout_alignParentBottom="true"
34         android:layout_alignParentLeft="true"/>
35 </RelativeLayout>
activity_item
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="wrap_content"
 5     android:padding="10dp">
 6 
 7     <TextView
 8         android:id="@+id/tv_title"
 9         android:layout_width="match_parent"
10         android:layout_height="wrap_content"
11         android:text="@string/app_name"
12         android:singleLine="true"/>
13 
14     <LinearLayout
15         android:id="@+id/line1"
16         android:layout_width="match_parent"
17         android:layout_height="60dp"
18         android:layout_below="@id/tv_title"
19         android:layout_marginTop="10dp">
20 
21         <ImageView
22             android:id="@+id/imageView1"
23             android:layout_width="100dp"
24             android:layout_height="60dp"
25             android:layout_weight="1"
26             android:layout_marginRight="10dp"
27             android:background="@mipmap/ic_launcher" />
28 
29         <ImageView
30             android:id="@+id/imageView2"
31             android:layout_width="100dp"
32             android:layout_height="60dp"
33             android:layout_weight="1"
34             android:layout_marginRight="10dp"
35             android:background="@mipmap/ic_launcher" />
36 
37         <ImageView
38             android:id="@+id/imageView3"
39             android:layout_width="100dp"
40             android:layout_height="60dp"
41             android:layout_weight="1"
42             android:background="@mipmap/ic_launcher" />
43     </LinearLayout>
44 
45     <TextView
46         android:layout_width="wrap_content"
47         android:layout_height="wrap_content"
48         android:textAppearance="?android:attr/textAppearanceSmall"
49         android:text="Small Text"
50         android:id="@+id/tv_time"
51         android:layout_below="@id/line1"
52         android:layout_alignParentLeft="true"/>
53 
54 
55 </RelativeLayout>
activity_item2

第一种是单张图片,第二种是三张图片。

 

在 ListView 添加的头部布局, 用 ViewPager 实现滑动的效果:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent">
 5 
 6     <android.support.v4.view.ViewPager
 7         android:id="@+id/vp"
 8         android:layout_width="match_parent"
 9         android:layout_height="200dp" />
10 
11     <TextView
12         android:id="@+id/tv_msg"
13         android:layout_width="wrap_content"
14         android:layout_height="wrap_content"
15         android:layout_centerHorizontal="true"
16         android:layout_marginBottom="5dp"
17         android:layout_alignBottom="@+id/vp"
18         android:textColor="#ddd"
19         android:text="吴建明和中国外交"
20         android:singleLine="true" />
21 
22 </RelativeLayout>
activity_item_header

 

最后是 ListView 的布局;

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:tools="http://schemas.android.com/tools"
 4     android:layout_width="match_parent"
 5     android:layout_height="match_parent"
 6     android:padding="10dp"
 7     tools:context="com.dragon.android.baseadapter.MainActivity">
 8 
 9     <ListView
10         android:layout_width="wrap_content"
11         android:layout_height="wrap_content"
12         android:scrollbars="none"
13         android:dividerHeight="1dp"
14         android:divider="#ccc"
15         android:id="@+id/listView"/>
16 </RelativeLayout>
activity_main

 

2)ListView 中要显示的数据这里先自己设定,不进行网络请求。

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <resources>
 3 
 4     <string-array name="titles">
 5         <item>那些被捕上岸的不寻常的大鱼,往往成为大家关注的焦点。一种奇观和一段足以津津乐道的传奇经历。</item>
 6         <item>自2008年正式推出,杭州公共自行车在国内外圈粉无数,它超越了一道风景、一张名片的定义,成为杭州的生活方式。</item>
 7         <item>奥运历史上,像美国队单独重赛这样荒诞的场面也不时出现。</item>
 8         <item>在巴西里约奥运赛场上,菲尔普斯身上“神秘的东方红圈”走红。</item>
 9         <item>里约奥运会正式启幕,为国出征的运动员激战正酣。而在奥运赛场之外,一大波隐藏的民间运动高手也蠢蠢欲动。</item>
10         <item>6月30日以来,第四轮强降雨给湖北造成严重损失。</item>
11         <item>查阅世界上城市地下排水系统中的佼佼者,可以发现,那些真正的良心下水道,即使多年过去,仍在发挥效用。</item>
12     </string-array>
13 
14     <string-array name="msgs">
15         <item>吴建明和中国外交</item>
16         <item>同性恋酒吧:是天堂也是地狱</item>
17         <item>那些年,我们这样过端午</item>
18         <item>马英九8年:从万人迷到受气包</item>
19         <item>朝鲜外宣里的幸福平壤</item>
20     </string-array>
21 
22 </resources>
arrays

图片资源可以自由添加

 

3)自定义适配器继承 BaseAdapter:

 1 package com.dragon.android.baseadapter;
 2 
 3 import android.content.Context;
 4 import android.view.LayoutInflater;
 5 import android.view.View;
 6 import android.view.ViewGroup;
 7 import android.widget.BaseAdapter;
 8 import android.widget.ImageView;
 9 import android.widget.TextView;
10 
11 import java.text.SimpleDateFormat;
12 import java.util.Date;
13 import java.util.List;
14 import java.util.Locale;
15 
16 /**
17  * Created by Auser on 2016/9/8.
18  */
19 public class MyAdapter extends BaseAdapter {
20 
21     private final Context context;
22     private List<Data> mData;
23 
24     public MyAdapter(Context context, List<Data> data) {
25         this.mData = data;
26         this.context = context;
27     }
28 
29     /**
30      * @return item 的数量
31      */
32     @Override
33     public int getCount() {
34         return mData == null ? 0 : mData.size();
35     }
36 
37     /**
38      * @param position
39      * @param convertView <重点: 得到每个 Item 将要显示的视图
40      * @param parent
41      * @return
42      */
43     @Override
44     public View getView(int position, View convertView, ViewGroup parent) {
45         View view;
46         Data data = getItem(position);
47         if (position % 3 == 0) {
48             view = LayoutInflater.from(context).inflate(R.layout.acyivity_item_2, parent, false);
49             ImageView imageView1 = (ImageView) view.findViewById(R.id.imageView1);
50             ImageView imageView2 = (ImageView) view.findViewById(R.id.imageView2);
51             ImageView imageView3 = (ImageView) view.findViewById(R.id.imageView3);
52             imageView1.setImageResource(data.getImgResId()[0]);
53             imageView2.setImageResource(data.getImgResId()[1]);
54             imageView3.setImageResource(data.getImgResId()[2]);
55 
56         } else {
57             view = LayoutInflater.from(context).inflate(R.layout.activity_item, parent, false);
58             ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
59             imageView.setImageResource(data.getImgResId()[0]);
60         }
61         TextView tv_title = (TextView) view.findViewById(R.id.tv_title);
62         tv_title.setText(data.getTitle());
63 
64         TextView tv_time = (TextView) view.findViewById(R.id.tv_time);
65         String time = new SimpleDateFormat("HH:mm", Locale.CHINA).format(new Date(data.getTime()));
66         tv_time.setText(time);
67         return view;
68     }
69 
70     /**
71      * 给开发者自己实现,一般用来的二道当前 position 位置的 数据
72      * 当 Item 可以在屏幕显示的时候,会调用 getView 且传递显示的 Item 的位置
73      *
74      * @param position 新显示的 Item 的位置
75      * @return
76      */
77     @Override
78     public Data getItem(int position) {
79         // Log.d("TAG", position + "");
80         return mData.get(position);
81     }
82 
83     /**
84      * @param position 当用户设置了 ListView 的Item 的点击时间的时候,将此值作为 第四个参数 传递
85      * @return
86      */
87     @Override
88     public long getItemId(int position) {
89         return 10086;
90     }
91 
92 }
MyAdapter

 

4)因为头部布局使用 ViewPager 实现,所以要添加自定义的适配器继承 PagerAdapter:

 1 package com.dragon.android.baseadapter;
 2 
 3 import android.support.v4.view.PagerAdapter;
 4 import android.view.View;
 5 import android.view.ViewGroup;
 6 import android.widget.ImageView;
 7 
 8 import java.util.List;
 9 
10 /**
11  * Created by Auser on 2016/9/8.
12  */
13 class MyPagerAdapter extends PagerAdapter {
14 
15     private List<ImageView> mList;
16 
17     public MyPagerAdapter(List<ImageView> mList) {
18         this.mList = mList;
19     }
20 
21     /**
22      * 决定ViewPager中能够显示几个子视图
23      * @return 可滑动的边界
24      */
25     @Override
26     public int getCount() {
27 
28         // 2的31次方-1
29         // mList.size=5:0--4
30         // position:0---9
31         // 0%5=0,4%5=4,
32         // 5%5=0,6%5=1....9%5=4
33         return Integer.MAX_VALUE;
34     }
35 
36     /**
37      * 产生item.container:容器.--->ViewPager
38      * @param container
39      * @param position
40      * @return
41      */
42     @Override
43     public Object instantiateItem(ViewGroup container, int position) {
44         // 将ImageView添加到ViewPager容器中.
45         container.addView(mList.get(position % mList.size()));
46 
47         return mList.get(position % mList.size());
48     }
49 
50     /**
51      * 判断当前的view是否是第一次产生的.
52      * @param view
53      * @param obj
54      * @return
55      */
56     @Override
57     public boolean isViewFromObject(View view, Object obj) {
58 
59         return view == obj;
60     }
61 
62     /**
63      * 移除一个item
64      * @param container
65      * @param position
66      * @param object
67      */
68     @Override
69     public void destroyItem(ViewGroup container, int position, Object object) {
70         // 从容器中移除视图
71         container.removeView(mList.get(position % mList.size()));
72     }
73 
74 }
MyPagerAdapter

这里面要注意如何实现 ViewPager 滑动时的循环效果 --- 即设置一个非常大的边界,循环显示。

 

5)需要一个容器来存放要展示的数据,这里封装一个 Data 类

 1 package com.dragon.android.baseadapter;
 2 
 3 import java.util.Arrays;
 4 
 5 /**
 6  * Created by Auser on 2016/9/8.
 7  */
 8 public class Data {
 9 
10     private int[] imgResId;
11     private String title;
12     private long time;
13 
14     @Override
15     public String toString() {
16         return "Data{" +
17                 "imgResId=" + Arrays.toString(imgResId) +
18                 ", title='" + title + '\'' +
19                 ", time=" + time +
20                 '}';
21     }
22 
23     public Data() {
24     }
25 
26     public Data(String title, int[] imgResId, long time) {
27         this.imgResId = imgResId;
28         this.title = title;
29         this.time = time;
30     }
31 
32     public int[] getImgResId() {
33         return imgResId;
34     }
35 
36     public void setImgResId(int[] imgResId) {
37         this.imgResId = imgResId;
38     }
39 
40     public String getTitle() {
41         return title;
42     }
43 
44     public void setTitle(String title) {
45         this.title = title;
46     }
47 
48     public long getTime() {
49         return time;
50     }
51 
52     public void setTime(long time) {
53         this.time = time;
54     }
55 }
Data

 

6)最后在 MainActivity 中对 ListView 和 ViewPager 配置适配器(同时实现文本随 ViewPager 的滑动同步改变)

 1 package com.dragon.android.baseadapter;
 2 
 3 import android.os.Bundle;
 4 import android.support.v4.view.ViewPager;
 5 import android.support.v7.app.AppCompatActivity;
 6 import android.view.View;
 7 import android.widget.ImageView;
 8 import android.widget.ListView;
 9 import android.widget.TextView;
10 
11 import java.util.ArrayList;
12 import java.util.List;
13 
14 public class MainActivity extends AppCompatActivity {
15 
16     private ListView listView;
17     private List<Data> mData;
18     private List<ImageView> mList;
19     private ViewPager mVp;
20     private TextView mTv;
21 
22     private int[] imgResIds = {R.mipmap.c1, R.mipmap.c2, R.mipmap.c3,
23             R.mipmap.c4, R.mipmap.c5, R.mipmap.c6, R.mipmap.c7, R.mipmap.c8,
24             R.mipmap.c9, R.mipmap.c10, R.mipmap.c11, R.mipmap.c12, R.mipmap.c13};
25 
26     private int[] imageHeaderIds = {R.mipmap.a1,R.mipmap.a2,R.mipmap.a3,R.mipmap.a4,R.mipmap.a5};
27 
28     @Override
29     protected void onCreate(Bundle savedInstanceState) {
30         super.onCreate(savedInstanceState);
31         setContentView(R.layout.activity_main);
32 
33         listView = (ListView) findViewById(R.id.listView);
34         String[] stringArray = getResources().getStringArray(R.array.titles);
35 
36         mData = new ArrayList<>();
37         initData(stringArray);
38 
39         addHeader();
40 
41         MyAdapter myAdapter = new MyAdapter(this, mData);
42         listView.setAdapter(myAdapter);
43     }
44 
45     /**
46      * 添加头部布局 ViewPager
47      */
48     private void addHeader() {
49         View view = getLayoutInflater().from(this).inflate(R.layout.activity_item_header, listView, false);
50         listView.addHeaderView(view);
51 
52         mVp = (ViewPager) view.findViewById(R.id.vp);
53         mTv = (TextView) view.findViewById(R.id.tv_msg);
54         String[] msgs = getResources().getStringArray(R.array.msgs);
55 
56         // 创建数据源.存放头部布局要展示的视图
57         mList = new ArrayList<ImageView>();
58         for (int i = 0; i < imageHeaderIds.length; i++) {
59             ImageView iv = new ImageView(this);
60             iv.setBackgroundResource(imageHeaderIds[i]);
61             mList.add(iv);
62         }
63         MyPagerAdapter adapter = new MyPagerAdapter(mList);
64         mVp.setAdapter(adapter);
65 
66         // 设置ViewPager当前是第几个视图
67         mVp.setCurrentItem(1000 * mList.size());
68 
69         // mVp.setOnPageChangeListener(listener);
70         mVp.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
71 
72             @Override
73             public void onPageSelected(int position) {
74                 String[] msgs = getResources().getStringArray(R.array.msgs);
75 
76                 // 让标题随着ViewPager的切换而切换
77                 mTv.setText(msgs[position % mList.size()]);
78             }
79         });
80     }
81 
82     /**
83      * 创建数据源
84      * @param stringArray
85      */
86     private void initData(String[] stringArray) {
87         int j = 0;
88         for (int i = 0; i < stringArray.length; i++) {
89             long l = System.currentTimeMillis();
90             if (i % 3 == 0) {
91                 mData.add(new Data(stringArray[i], new int[]{imgResIds[j++], imgResIds[j++], imgResIds[j++]}, l + 1000000 * i));
92             } else {
93                 mData.add(new Data(stringArray[i], new int[]{imgResIds[j++]}, l + 1000000 * i));
94             }
95         }
96     }
97 }

 

******************************************

posted on 2016-09-09 13:39  西门吃雪  阅读(2431)  评论(0编辑  收藏  举报

导航