仿网易新闻效果android源码分析

转于:

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2013/0202/826.html

------------------------------------------------------------------------------------------------------

摘要 一直想知道这种效果到底是如何做出来的,直到看到代码,原来还是动画。从网上找了两份代码,原理基本相同,两份代码中应该有相互参考部分,现在简单解析下,做一个记录,另外,代码中做了些许不妨碍功能的修改(如果有时间的话,自己也会考虑用 fragment 实

一直想知道这种效果到底是如何做出来的,直到看到代码,原来还是动画。从网上找了两份代码,原理基本相同,两份代码中应该有相互参考部分,现在简单解析下,做一个记录,另外,代码中做了些许不妨碍功能的修改(如果有时间的话,自己也会考虑用fragment实现下)。先看下效果图:


这里主要讲解的是以下部分:


先看下注释里面的说明:

1
2
3
4
5
6
7
/**
  * Android实现局部图片滑动指引效果
  * @Description: 实现以下功能:
  * 1、顶部单张图片左右拖拉滑动;
  * 2、带指引;
  * 3、仅滑动顶部单张图片,不滑动页面,下面的图文内容不动;
  * 4、类似于新闻客户端的功能

看下它的主Activity里面的全局变量(也就是上面图形):

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
public class MainActivity extends ActivityGroup implements OnClickListener{
     // 选中的新闻条目
     private TextView mSelectedItem = null ;
     // 头部新闻条目的Layout
     private RelativeLayout mHeader = null ;
     // 中间新闻主体的Layout
     private RelativeLayout mNewsMainLayout = null ;
     private LayoutParams params = null ;
     //顶部提示
     private TextView mNetEaseTop = null ;
     // 新闻分类
     private TextView mNewsItem = null ;
     private TextView mInfoItem = null ;
     private TextView mBlogItem = null ;
     private TextView mMagezineItem = null ;
     private TextView mDomainItem = null ;
     private TextView mMoreItem = null ;
      
     // 新闻分类中每条分类的宽度
     private int mItemWidth = 0;
     // 条目背景移动开始位置
     private int startX = 0;
     private Intent mIntent = null ;
     // 设置新闻主题
     private View mNewsMain = null ;

注释比较详细。可以看到这个activity继承自activityGroup类,而activityGroup类在3.0以后是deprecated,所以在开头说想要用fragment重新实现一下。

1
Deprecated. Use the new Fragment and FragmentManager APIs instead; these are also available on older platforms through the Android compatibility package.

再看onCreate方法:

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
@Override
     public void onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.main);     
         // 初始化控件
         initeViews();
     }
      
     /**
      * 初始化控件
      */
     private void initeViews(){
         mNewsItem = (TextView) findViewById(R.id.tv_title_news);
         mInfoItem = (TextView) findViewById(R.id.tv_title_info);
         mBlogItem = (TextView) findViewById(R.id.tv_title_blog);
         mMagezineItem = (TextView) findViewById(R.id.tv_title_magazine);
         mDomainItem = (TextView) findViewById(R.id.tv_title_domain);
         mMoreItem = (TextView) findViewById(R.id.tv_title_more);
          
         mNewsItem.setOnClickListener( this );
         mInfoItem.setOnClickListener( this );
         mBlogItem.setOnClickListener( this );
         mMagezineItem.setOnClickListener( this );
         mDomainItem.setOnClickListener( this );
         mMoreItem.setOnClickListener( this );
  
         // 设置选中条目属性
         mSelectedItem = new TextView( this );
         mSelectedItem.setText(R.string.title_news_category_tops);
         mSelectedItem.setTextColor(Color.WHITE);
         mSelectedItem.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 17);
         mSelectedItem.setGravity(Gravity.CENTER);
         mSelectedItem.setWidth((getScreenWidth() - DimensionUtility.dip2px( this , 20)) / 6);
         mSelectedItem.setBackgroundResource(R.drawable.slidebar);
         RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(
                 LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
         param.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
          
         mHeader = (RelativeLayout) findViewById(R.id.layout_title_bar);
         mNetEaseTop = (TextView) findViewById(R.id.tv_netease_top);
          
         mHeader.addView(mSelectedItem, param);
          
         // 设置头条新闻主体
         mIntent = new Intent(MainActivity. this , TopicNews.class);
         mNewsMain = getLocalActivityManager().startActivity(
                 "TopicNews" , mIntent).getDecorView();
         params = new LayoutParams(
                 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
         mNewsMainLayout = (RelativeLayout) findViewById(R.id.layout_news_main);
         mNewsMainLayout.addView(mNewsMain, params);
     }

这里所说的选中条目,就是上图中,选中的高亮部分,它其实可以理解为和下面六个是上下两层的关系。而mNetEaseTop是指的


这一块内容,在原代码中,作者并未做这一块和下面内容的同时更新,个人后来加上。设置头条新闻主题下面就是设置默认选择项:第一项(头条新闻)。

再来看一下里面用到的布局文件:

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
60
61
62
63
64
65
66
<?xml version= "1.0" encoding= "utf-8" ?>
<LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"
     android:layout_width= "fill_parent"
     android:layout_height= "fill_parent"
     android:orientation= "vertical"
     android:weightSum= "10" >
  
     <include
         android:id= "@+id/header"
         layout= "@layout/header" />
  
     <RelativeLayout
         android:id= "@+id/layout_news_main"
         android:layout_width= "fill_parent"
         android:layout_height= "0dp"
         android:layout_weight= "9" >
     </RelativeLayout>
  
     <RelativeLayout
         android:id= "@+id/layout_bottom"
         android:layout_weight= "1"
         android:layout_width= "fill_parent"
         android:layout_height= "wrap_content" >
  
         <RadioGroup
             android:id= "@+id/radiogroup"
             android:layout_width= "fill_parent"
             android:layout_height= "0dp"
             android:background= "@drawable/bottombg"
             android:gravity= "center_vertical"
             android:orientation= "horizontal" >
  
             <RadioButton
                 android:id= "@+id/radio_news"
                 android:layout_width= "wrap_content"
                 android:background= "@drawable/tab_selector_news"
                 android:button= "@null"
                 android:checked= "true" />
  
             <RadioButton
                 android:id= "@+id/radio_topic"
                 android:layout_width= "wrap_content"
                 android:background= "@drawable/tab_selector_topic"
                 android:button= "@null" />
  
             <RadioButton
                 android:id= "@+id/radio_pic"
                 android:layout_width= "wrap_content"
                 android:background= "@drawable/tab_selector_pic"
                 android:button= "@null" />
  
             <RadioButton
                 android:id= "@+id/radio_follow"
                 android:layout_width= "wrap_content"
                 android:background= "@drawable/tab_selector_follow"
                 android:button= "@null" />
  
             <RadioButton
                 android:id= "@+id/radio_vote"
                 android:layout_width= "wrap_content"
                 android:background= "@drawable/tab_selector_vote"
                 android:button= "@null" />
         </RadioGroup>
     </RelativeLayout>
  
</LinearLayout>

中间的layout_new_main就是mNewsMainLayout,起到一个占位的作用,下面的RadioGroup就是最下面的标记栏。里面用到的布局文件主要是header.xml:

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
<?xml version= "1.0" encoding= "utf-8" ?>
<LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"
     android:layout_width= "fill_parent"
     android:layout_height= "wrap_content"
     android:orientation= "vertical" >
  
     <RelativeLayout
         android:id= "@+id/layout_top"
         android:layout_width= "match_parent"
         android:layout_height= "40dip"
         android:background= "#990000" >
  
         <TextView
             android:id= "@+id/tv_netease_top"
             android:layout_width= "wrap_content"
             android:layout_height= "wrap_content"
             android:layout_centerVertical= "true"
             android:layout_marginLeft= "10dip"
             android:textSize= "20sp"
             android:textColor= "@android:color/white"
             android:text= "@string/news_top_left_text1" />
  
         <TextView
             android:layout_width= "wrap_content"
             android:layout_height= "wrap_content"
             android:layout_centerVertical= "true"
             android:layout_toRightOf= "@+id/tv_netease_top"
             android:text= "@string/news_top_left_text2"
             android:textColor= "@android:color/white"
             android:textSize= "20sp" />
  
         <ImageView
             android:layout_width= "wrap_content"
             android:layout_height= "wrap_content"
             android:layout_alignParentRight= "true"
             android:src= "@drawable/duoyun"
             android:contentDescription= "@string/img_duoyun_desc" />
          
     </RelativeLayout>
  
     <RelativeLayout
         android:id= "@+id/layout_title_bar"
         android:layout_width= "fill_parent"
         android:layout_height= "40dip"
         android:paddingLeft= "5dip"
         android:paddingRight= "5dip"
         android:background= "@drawable/bg_header_top" >
  
         <LinearLayout
             android:id= "@+id/header_item"
             android:layout_width= "fill_parent"
             android:layout_height= "match_parent"
             android:orientation= "horizontal" >
  
             <RelativeLayout
                 android:id= "@+id/layout"
                 android:layout_width= "match_parent"
                 android:layout_height= "match_parent"
                 android:layout_weight= "1" >
  
                 <TextView
                     android:id= "@+id/tv_title_news"
                     android:layout_width= "match_parent"
                     android:layout_height= "match_parent"
                     android:layout_centerInParent= "true"
                     style= "@style/header_title_style"
                     android:gravity= "center"
                     android:text= "@string/title_news_category_tops" />
                  
             </RelativeLayout>
  
             <RelativeLayout
                 android:layout_width= "match_parent"
                 android:layout_height= "match_parent"
                 android:layout_weight= "1" >
  
                 <TextView
                     android:id= "@+id/tv_title_info"
                     android:layout_width= "match_parent"
                     android:layout_height= "match_parent"
                     android:layout_centerInParent= "true"
                     style= "@style/header_title_style"
                     android:gravity= "center"
                     android:text= "@string/title_news_category_info" />
                  
             </RelativeLayout>
  
             <RelativeLayout
                 android:layout_width= "match_parent"
                 android:layout_height= "match_parent"
                 android:layout_weight= "1" >
  
                 <TextView
                     android:id= "@+id/tv_title_blog"
                     android:layout_width= "match_parent"
                     android:layout_height= "match_parent"
                     android:layout_centerInParent= "true"
                     style= "@style/header_title_style"
                     android:gravity= "center"
                     android:text= "@string/title_news_category_blog" />
                  
             </RelativeLayout>
  
             <RelativeLayout
                 android:layout_width= "match_parent"
                 android:layout_height= "match_parent"
                 android:layout_weight= "1" >
  
                 <TextView
                     android:id= "@+id/tv_title_magazine"
                     android:layout_width= "match_parent"
                     android:layout_height= "match_parent"
                     android:layout_centerInParent= "true"
                     style= "@style/header_title_style"
                     android:gravity= "center"
                     android:text= "@string/title_news_category_magazine" />
                  
             </RelativeLayout>
  
             <RelativeLayout
                 android:layout_width= "match_parent"
                 android:layout_height= "match_parent"
                 android:layout_weight= "1" >
  
                 <TextView
                     android:id= "@+id/tv_title_domain"
                     android:layout_width= "match_parent"
                     android:layout_height= "match_parent"
                     android:layout_centerInParent= "true"
                     style= "@style/header_title_style"
                     android:gravity= "center"
                     android:text= "@string/title_news_category_domain" />
                  
             </RelativeLayout>
  
             <RelativeLayout
                 android:layout_width= "match_parent"
                 android:layout_height= "match_parent"
                 android:layout_weight= "1" >
  
                 <TextView
                     android:id= "@+id/tv_title_more"
                     android:layout_width= "match_parent"
                     android:layout_height= "match_parent"
                     android:layout_centerInParent= "true"
                     style= "@style/header_title_style"
                     android:gravity= "center"
                     android:text= "@string/title_news_category_more" />
             </RelativeLayout>
         </LinearLayout>
     </RelativeLayout>
</LinearLayout>

比较简单的布局,不详述。

上面代码设置选中项宽带:

1
mSelectedItem.setWidth((getScreenWidth() - DimensionUtility.dip2px( this , 20)) / 6);

用到了getScreenWidth方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
      * 获取屏幕的宽度
      * @return
      */
     private int getScreenWidth(){
         WindowManager windowManager = getWindowManager();
         Display display = windowManager.getDefaultDisplay();
//      Point point = new Point();
//      display.getSize(point);
//      int screenWidth = point.x;
         int screenWidth = display.getWidth();
         return screenWidth;
     }

display的getWidth方法在3.0中好像也没deprecated。可以使用注释掉的代码获取屏幕宽度。

下面是最重要的部分点击切换:

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// 新闻分类事件监听
     @Override
     public void onClick(View v) {
         mItemWidth = findViewById(R.id.layout).getWidth();
          
         switch (v.getId()) {
         case R.id.tv_title_news:
             //动画滑动
             ImageAnimation.SetImageSlide(mSelectedItem, startX, 0, 0, 0);
             //设置滑动后动画开始位置
             startX = 0;
             //设置选中项显示文字,也就是高亮部分文字
             mSelectedItem.setText(R.string.title_news_category_tops);
             //设置左上角提示文字
             mNetEaseTop.setText(R.string.title_news_category_tops);
              
             // 显示头条信息
             mIntent.setClass(MainActivity. this , TopicNews.class);
             mNewsMain = getLocalActivityManager().startActivity(
                     "TopicNews" , mIntent).getDecorView();
             break ;
         case R.id.tv_title_info:
             ImageAnimation.SetImageSlide(mSelectedItem, startX, mItemWidth, 0, 0);
             startX = mItemWidth;
             mSelectedItem.setText(R.string.title_news_category_info);
             mNetEaseTop.setText(R.string.title_news_category_info);
              
             // 显示资讯信息
             mIntent.setClass(MainActivity. this , InfoNews.class);
             mNewsMain = getLocalActivityManager().startActivity(
                     "InfoNews" , mIntent).getDecorView();
             break ;
         case R.id.tv_title_blog:
             ImageAnimation.SetImageSlide(mSelectedItem, startX, mItemWidth * 2, 0, 0);
             startX = mItemWidth * 2;
             mSelectedItem.setText(R.string.title_news_category_blog);
             mNetEaseTop.setText(R.string.title_news_category_blog);
              
             // 显示博客信息
             mIntent.setClass(MainActivity. this , BlogNews.class);
             mNewsMain = getLocalActivityManager().startActivity(
                     "BlogNews" , mIntent).getDecorView();
             break ;
         case R.id.tv_title_magazine:
             ImageAnimation.SetImageSlide(mSelectedItem, startX, mItemWidth * 3, 0, 0);
             startX = mItemWidth * 3;
             mSelectedItem.setText(R.string.title_news_category_magazine);
             mNetEaseTop.setText(R.string.title_news_category_magazine);
              
             // 显示杂志信息
             mIntent.setClass(MainActivity. this , MagazineNews.class);
             mNewsMain = getLocalActivityManager().startActivity(
                     "MagazineNews" , mIntent).getDecorView();
             break ;
         case R.id.tv_title_domain:
             ImageAnimation.SetImageSlide(mSelectedItem, startX, mItemWidth * 4, 0, 0);
             startX = mItemWidth * 4;
             mSelectedItem.setText(R.string.title_news_category_domain);
             mNetEaseTop.setText(R.string.title_news_category_domain);
             // 显示业界信息
             mIntent.setClass(MainActivity. this , DomainNews.class);
             mNewsMain = getLocalActivityManager().startActivity(
                     "DomainNews" , mIntent).getDecorView();
             break ;
         case R.id.tv_title_more:
             ImageAnimation.SetImageSlide(mSelectedItem, startX, mItemWidth * 5, 0, 0);
             startX = mItemWidth * 5;
             mSelectedItem.setText(R.string.title_news_category_more);
             mNetEaseTop.setText(R.string.title_news_category_more);
              
             // 显示更多信息
             mIntent.setClass(MainActivity. this , MoreNews.class);
             mNewsMain = getLocalActivityManager().startActivity(
                     "MoreNews" , mIntent).getDecorView();
             break ;
         default :
             break ;
         }      
         // 更换Layout中的新闻主体
         mNewsMainLayout.removeAllViews();
         mNewsMainLayout.addView(mNewsMain, params);
     }

在注释中,解释的已经比较清楚了,看一下ImageAnimation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class ImageAnimation {
     /**
      * 设置图像移动动画效果
      * @param v
      * @param startX
      * @param toX
      * @param startY
      * @param toY
      */
     public static void SetImageSlide(View v, int startX, int toX, int startY, int toY) {
         TranslateAnimation anim = new TranslateAnimation(startX, toX, startY, toY);
         anim.setDuration(100);
         anim.setFillAfter( true );
         v.startAnimation(anim);
     }
}

就是一个简单的移动动画。这样就是简单的顶部标示就完成了,接下来要分析如下:


 

这个代码在TopicNews中,先看下使用到的全局变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class TopicNews extends Activity{
     // 滑动图片的集合
     private ArrayList<View> mImagePageViewList = null ;
     private ViewGroup mMainView = null ;
     private ViewPager mViewPager = null ;
     // 当前ViewPager索引
//  private int pageIndex = 0;
      
     // 包含圆点图片的View
     private ViewGroup mImageCircleView = null ;
     private ImageView[] mImageCircleViews = null ;
      
     // 滑动标题
     private TextView mSlideTitle = null ;
      
     // 布局设置类
     private SlideImageLayout mSlideLayout = null ;
     // 数据解析类
     private NewsXmlParser mParser = null ;

 里面的viewPager类是用于滑动控件,SlideImageLayout类是用于上面图片和下面标志点的布局。NewsXmlParser类提供数据。

看一下onCreate方法:

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
@Override
protected void onCreate(Bundle savedInstanceState) {
     super .onCreate(savedInstanceState);
     setTheme(android.R.style.Theme_Translucent_NoTitleBar);    
     // 初始化
     initeViews();
}
  
/**
  * 初始化
  */
private void initeViews(){
     // 滑动图片区域
     mImagePageViewList = new ArrayList<View>();
     LayoutInflater inflater = getLayoutInflater(); 
     mMainView = (ViewGroup)inflater.inflate(R.layout.page_topic_news, null );
     mViewPager = (ViewPager) mMainView.findViewById(R.id.image_slide_page); 
      
     // 圆点图片区域
     mParser = new NewsXmlParser();
     int length = mParser.getSlideImages().length;
     mImageCircleViews = new ImageView[length];
     mImageCircleView = (ViewGroup) mMainView.findViewById(R.id.layout_circle_images);
     mSlideLayout = new SlideImageLayout(TopicNews. this );
     mSlideLayout.setCircleImageLayout(length);
      
     for (int i = 0; i < length; i++){
         mImagePageViewList.add(mSlideLayout.getSlideImageLayout(mParser.getSlideImages()[i]));
         mImageCircleViews[i] = mSlideLayout.getCircleImageLayout(i);
         mImageCircleView.addView(mSlideLayout.getLinearLayout(mImageCircleViews[i], 10, 10));
     }
      
     // 设置默认的滑动标题
     mSlideTitle = (TextView) mMainView.findViewById(R.id.tvSlideTitle);
     mSlideTitle.setText(mParser.getSlideTitles()[0]);
      
     setContentView(mMainView);
      
     // 设置ViewPager
     mViewPager.setAdapter( new SlideImageAdapter()); 
     mViewPager.setOnPageChangeListener( new ImagePageChangeListener());
}

看一下远点图片区域:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 圆点图片区域
         mParser = new NewsXmlParser();
         int length = mParser.getSlideImages().length;
         mImageCircleViews = new ImageView[length];
         mImageCircleView = (ViewGroup) mMainView.findViewById(R.id.layout_circle_images);
         mSlideLayout = new SlideImageLayout(TopicNews. this );
         mSlideLayout.setCircleImageLayout(length);
          
         for (int i = 0; i < length; i++){
             mImagePageViewList.add(mSlideLayout.getSlideImageLayout(mParser.getSlideImages()[i]));
             mImageCircleViews[i] = mSlideLayout.getCircleImageLayout(i);
             mImageCircleView.addView(mSlideLayout.getLinearLayout(mImageCircleViews[i], 10, 10));
         }

里面主要是调用了NewsXmlParser类和SlideImageLayout的方法,那就先看下NewsXmlParser的getSlideImages方法:

1
2
3
public int[] getSlideImages(){
         return slideImages;
     }

这里的slideImage是在类中定义好的:

1
2
3
4
5
6
7
// 滑动图片的集合,这里设置成了固定加载,当然也可动态加载。
     private int[] slideImages = {
             R.drawable.image01,
             R.drawable.image02,
             R.drawable.image03,
             R.drawable.image04,
             R.drawable.image05};

那看一下用到的SlideImageLayout类的getSlideImageLayout:获取图片的布局:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
      * 生成滑动图片区域布局
      * @param id
      * @return
      */
     public View getSlideImageLayout(int id){
         // 包含TextView的LinearLayout
         LinearLayout imageLinerLayout = new LinearLayout(mContext);
         LinearLayout.LayoutParams imageLinerLayoutParames = new LinearLayout.LayoutParams(
                 LinearLayout.LayoutParams.WRAP_CONTENT,
                 LinearLayout.LayoutParams.WRAP_CONTENT,
                 1);
          
         ImageView iv = new ImageView(mContext);
         iv.setBackgroundResource(id);
         iv.setOnClickListener( new ImageOnClickListener());
         imageLinerLayout.addView(iv,imageLinerLayoutParames);
         mImageList.add(iv);
          
         return imageLinerLayout;
     }

创建一个layout,然后再创建一个imageView,把ImageView加入到layout中,然后返回layout。同理,我们再看下set和getCircleImageLayout:

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
* 设置圆点个数
     * @param size
     */
    public void setCircleImageLayout(int size){
        mImageViews = new ImageView[size];
    }
     
    /**
     * 生成圆点图片区域布局对象
     * @param index
     * @return
     */
    public ImageView getCircleImageLayout(int index){
        mImageView = new ImageView(mContext); 
        mImageView.setLayoutParams( new LayoutParams(10,10));
        mImageView.setScaleType(ScaleType.FIT_XY);
         
        mImageViews[index] = mImageView;
          
        if (index == 0) { 
            //默认选中第一张图片
            mImageViews[index].setBackgroundResource(R.drawable.dot_selected); 
        } else
            mImageViews[index].setBackgroundResource(R.drawable.dot_none); 
       
          
        return mImageViews[index];
    }

获取圆点图片的Image,然后返回。

在initViews中还有设置滑动图片标题:

1
2
3
4
5
// 设置默认的滑动标题
         mSlideTitle = (TextView) mMainView.findViewById(R.id.tvSlideTitle);
         mSlideTitle.setText(mParser.getSlideTitles()[0]);
          
         setContentView(mMainView);

最后是设置Viewpager的Adapter还有监听

1
2
3
// 设置ViewPager
         mViewPager.setAdapter( new SlideImageAdapter()); 
         mViewPager.setOnPageChangeListener( new ImagePageChangeListener());

先来看下SlideImageAdapter类:

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
// 滑动图片数据适配器
     private class SlideImageAdapter extends PagerAdapter { 
         @Override 
         public int getCount() {
             return mImagePageViewList.size(); 
        
    
         @Override 
         public boolean isViewFromObject(View view, Object object) { 
             return view == object; 
        
    
         @Override 
         public int getItemPosition(Object object) { 
             return super .getItemPosition(object); 
        
    
         @Override 
         public void destroyItem(View view, int arg1, Object arg2) { 
             ((ViewPager) view).removeView(mImagePageViewList.get(arg1)); 
        
    
         @Override 
         public Object instantiateItem(View view, int position) { 
             ((ViewPager) view).addView(mImagePageViewList.get(position));
              
             return mImagePageViewList.get(position); 
        
    
         @Override 
         public void restoreState(Parcelable arg0, ClassLoader arg1) { 
    
        
    
         @Override 
         public Parcelable saveState() { 
             return null
        
    
         @Override 
         public void startUpdate(View arg0) { 
        
    
         @Override 
         public void finishUpdate(View arg0) { 
        
     }

一个典型的适配器类,主要看下面两个方法:

1
2
3
4
5
6
7
8
9
10
11
@Override 
         public void destroyItem(View view, int arg1, Object arg2) { 
             ((ViewPager) view).removeView(mImagePageViewList.get(arg1)); 
        
    
         @Override 
         public Object instantiateItem(View view, int position) { 
             ((ViewPager) view).addView(mImagePageViewList.get(position));
              
             return mImagePageViewList.get(position); 
         }

实例化Item和销毁Item。我们在initViews方法里面为mImagePageViewList里面加载了很多view,在这里取出,加入到ViewPager中去。

其实他的滑动监听事件特别简单,就是改变下选中图片、标识圆点和标题文字:

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
// 滑动页面更改事件监听器
     private class ImagePageChangeListener implements OnPageChangeListener {
         @Override 
         public void onPageScrollStateChanged(int arg0) { 
        
    
         @Override 
         public void onPageScrolled(int arg0, float arg1, int arg2) { 
        
    
         @Override 
         public void onPageSelected(int index) { 
//          pageIndex = index;
             mSlideLayout.setPageIndex(index);
             mSlideTitle.setText(mParser.getSlideTitles()[index]);
              
             for (int i = 0; i < mImageCircleViews.length; i++) { 
                 mImageCircleViews[index].setBackgroundResource(R.drawable.dot_selected);
                  
                 if (index != i) { 
                     mImageCircleViews[i].setBackgroundResource(R.drawable.dot_none); 
                
             }
        
     }

还有,在网易新闻里,有个底部标记栏:

这个功能是如何实现的呢?

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
<RelativeLayout
         android:id= "@+id/layout_bottom"
         android:layout_weight= "1"
         android:layout_width= "fill_parent"
         android:layout_height= "wrap_content" >
  
         <RadioGroup
             android:id= "@+id/radiogroup"
             android:layout_width= "fill_parent"
             android:layout_height= "0dp"
             android:background= "@drawable/bottombg"
             android:gravity= "center_vertical"
             android:orientation= "horizontal" >
  
             <RadioButton
                 android:id= "@+id/radio_news"
                 android:layout_width= "wrap_content"
                 android:background= "@drawable/tab_selector_news"
                 android:button= "@null"
                 android:checked= "true" />
  
             <RadioButton
                 android:id= "@+id/radio_topic"
                 android:layout_width= "wrap_content"
                 android:background= "@drawable/tab_selector_topic"
                 android:button= "@null" />
  
             <RadioButton
                 android:id= "@+id/radio_pic"
                 android:layout_width= "wrap_content"
                 android:background= "@drawable/tab_selector_pic"
                 android:button= "@null" />
  
             <RadioButton
                 android:id= "@+id/radio_follow"
                 android:layout_width= "wrap_content"
                 android:background= "@drawable/tab_selector_follow"
                 android:button= "@null" />
  
             <RadioButton
                 android:id= "@+id/radio_vote"
                 android:layout_width= "wrap_content"
                 android:background= "@drawable/tab_selector_vote"
                 android:button= "@null" />
         </RadioGroup>
     </RelativeLayout>


其中background图片:

1
2
3
4
5
6
7
<?xml version= "1.0" encoding= "utf-8" ?>
<selector xmlns:android= "http://schemas.android.com/apk/res/android" >
  
     <item android:drawable= "@drawable/current_topic_tab" android:state_checked= "true" />
     <item android:drawable= "@drawable/back_topic_tab" android:state_checked= "false" />
  
</selector>

切换代码:

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
@Override
     public void onCheckedChanged(RadioGroup group, int checkedId) {
  
         switch (checkedId) {
         case R.id.radio_news:
             ImageAnimation.SetImageSlide(mImageView, startLeft, 0, 0, 0);
             startLeft = 0;
             break ;
         case R.id.radio_topic:
             ImageAnimation.SetImageSlide(mImageView, startLeft, mImageView.getWidth(), 0, 0);
             startLeft = mImageView.getWidth();
          
             break ;
         case R.id.radio_pic:
             ImageAnimation.SetImageSlide(mImageView, startLeft, mImageView.getWidth() * 2, 0, 0);
             startLeft = mImageView.getWidth() * 2;
             break ;
         case R.id.radio_follow:
             ImageAnimation.SetImageSlide(mImageView, startLeft, mImageView.getWidth() * 3, 0, 0);
             startLeft = mImageView.getWidth() * 3;
             break ;
         case R.id.radio_vote:
             ImageAnimation.SetImageSlide(mImageView, startLeft, mImageView.getWidth() * 4, 0, 0);
             startLeft = mImageView.getWidth() * 4;
             break ;
  
         default :
             break ;
         }
     

最后代码下载地址:

http://download.csdn.net/detail/aomandeshangxiao/4751356

猜你喜欢

转载自yuemeiqing2008-163-com.iteye.com/blog/2136248