现在的位置: 首页 > 综合 > 正文

仿网易新闻效果源码分析(含菜单设计)

2013年08月11日 ⁄ 综合 ⁄ 共 16981字 ⁄ 字号 评论关闭

http://blog.csdn.net/aomandeshangxiao/article/details/8158128

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


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


先看下注释里面的说明:

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

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

  1. public class MainActivity extends ActivityGroup implements OnClickListener{  
  2.     // 选中的新闻条目  
  3.     private TextView mSelectedItem = null;  
  4.     // 头部新闻条目的Layout  
  5.     private RelativeLayout mHeader = null;  
  6.     // 中间新闻主体的Layout  
  7.     private RelativeLayout mNewsMainLayout = null;  
  8.     private LayoutParams params = null;  
  9.     //顶部提示  
  10.     private TextView mNetEaseTop = null;  
  11.     // 新闻分类  
  12.     private TextView mNewsItem = null;  
  13.     private TextView mInfoItem = null;  
  14.     private TextView mBlogItem = null;  
  15.     private TextView mMagezineItem = null;  
  16.     private TextView mDomainItem = null;  
  17.     private TextView mMoreItem = null;  
  18.       
  19.     // 新闻分类中每条分类的宽度  
  20.     private int mItemWidth = 0;  
  21.     // 条目背景移动开始位置  
  22.     private int startX = 0;  
  23.     private Intent mIntent = null;  
  24.     // 设置新闻主题  
  25.     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. @Override  
  2.     public void onCreate(Bundle savedInstanceState) {  
  3.         super.onCreate(savedInstanceState);  
  4.         setContentView(R.layout.main);        
  5.         // 初始化控件  
  6.         initeViews();  
  7.     }  
  8.       
  9.     /** 
  10.      * 初始化控件 
  11.      */  
  12.     private void initeViews(){  
  13.         mNewsItem = (TextView) findViewById(R.id.tv_title_news);  
  14.         mInfoItem = (TextView) findViewById(R.id.tv_title_info);  
  15.         mBlogItem = (TextView) findViewById(R.id.tv_title_blog);  
  16.         mMagezineItem = (TextView) findViewById(R.id.tv_title_magazine);  
  17.         mDomainItem = (TextView) findViewById(R.id.tv_title_domain);  
  18.         mMoreItem = (TextView) findViewById(R.id.tv_title_more);  
  19.           
  20.         mNewsItem.setOnClickListener(this);  
  21.         mInfoItem.setOnClickListener(this);  
  22.         mBlogItem.setOnClickListener(this);  
  23.         mMagezineItem.setOnClickListener(this);  
  24.         mDomainItem.setOnClickListener(this);  
  25.         mMoreItem.setOnClickListener(this);  
  26.   
  27.         // 设置选中条目属性  
  28.         mSelectedItem = new TextView(this);  
  29.         mSelectedItem.setText(R.string.title_news_category_tops);  
  30.         mSelectedItem.setTextColor(Color.WHITE);  
  31.         mSelectedItem.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 17);  
  32.         mSelectedItem.setGravity(Gravity.CENTER);  
  33.         mSelectedItem.setWidth((getScreenWidth() - DimensionUtility.dip2px(this20)) / 6);  
  34.         mSelectedItem.setBackgroundResource(R.drawable.slidebar);  
  35.         RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(  
  36.                 LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);  
  37.         param.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);  
  38.           
  39.         mHeader = (RelativeLayout) findViewById(R.id.layout_title_bar);  
  40.         mNetEaseTop = (TextView) findViewById(R.id.tv_netease_top);  
  41.           
  42.         mHeader.addView(mSelectedItem, param);  
  43.           
  44.         // 设置头条新闻主体  
  45.         mIntent = new Intent(MainActivity.this, TopicNews.class);  
  46.         mNewsMain = getLocalActivityManager().startActivity(  
  47.                 "TopicNews", mIntent).getDecorView();  
  48.         params = new LayoutParams(  
  49.                 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);  
  50.         mNewsMainLayout = (RelativeLayout) findViewById(R.id.layout_news_main);  
  51.         mNewsMainLayout.addView(mNewsMain, params);  
  52.     }  

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


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

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

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:orientation="vertical"  
  6.     android:weightSum="10" >  
  7.   
  8.     <include  
  9.         android:id="@+id/header"  
  10.         layout="@layout/header" />  
  11.   
  12.     <RelativeLayout  
  13.         android:id="@+id/layout_news_main"  
  14.         android:layout_width="fill_parent"  
  15.         android:layout_height="0dp"  
  16.         android:layout_weight="9" >  
  17.     </RelativeLayout>  
  18.   
  19.     <RelativeLayout  
  20.         android:id="@+id/layout_bottom"  
  21.         android:layout_weight="1"  
  22.         android:layout_width="fill_parent"  
  23.         android:layout_height="wrap_content" >  
  24.   
  25.         <RadioGroup  
  26.             android:id="@+id/radiogroup"  
  27.             android:layout_width="fill_parent"  
  28.             android:layout_height="0dp"  
  29.             android:background="@drawable/bottombg"  
  30.             android:gravity="center_vertical"  
  31.             android:orientation="horizontal" >  
  32.   
  33.             <RadioButton  
  34.                 android:id="@+id/radio_news"  
  35.                 android:layout_width="wrap_content"  
  36.                 android:background="@drawable/tab_selector_news"  
  37.                 android:button="@null"  
  38.                 android:checked="true" />  
  39.   
  40.             <RadioButton  
  41.                 android:id="@+id/radio_topic"  
  42.                 android:layout_width="wrap_content"  
  43.                 android:background="@drawable/tab_selector_topic"  
  44.                 android:button="@null" />  
  45.   
  46.             <RadioButton  
  47.                 android:id="@+id/radio_pic"  
  48.                 android:layout_width="wrap_content"  
  49.                 android:background="@drawable/tab_selector_pic"  
  50.                 android:button="@null" />  
  51.   
  52.             <RadioButton  
  53.                 android:id="@+id/radio_follow"  
  54.                 android:layout_width="wrap_content"  
  55.                 android:background="@drawable/tab_selector_follow"  
  56.                 android:button="@null" />  
  57.   
  58.             <RadioButton  
  59.                 android:id="@+id/radio_vote"  
  60.                 android:layout_width="wrap_content"  
  61.                 android:background="@drawable/tab_selector_vote"  
  62.                 android:button="@null" />  
  63.         </RadioGroup>  
  64.     </RelativeLayout>  
  65.   
  66. </LinearLayout>  



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

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="wrap_content"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <RelativeLayout  
  8.         android:id="@+id/layout_top"  
  9.         android:layout_width="match_parent"  
  10.         android:layout_height="40dip"  
  11.         android:background="#990000" >  
  12.   
  13.         <TextView  
  14.             android:id="@+id/tv_netease_top"  
  15.             android:layout_width="wrap_content"  
  16.             android:layout_height="wrap_content"  
  17.             android:layout_centerVertical="true"  
  18.             android:layout_marginLeft="10dip"  
  19.             android:textSize="20sp"  
  20.             android:textColor="@android:color/white"  
  21.             android:text="@string/news_top_left_text1" />  
  22.   
  23.         <TextView  
  24.             android:layout_width="wrap_content"  
  25.             android:layout_height="wrap_content"  
  26.             android:layout_centerVertical="true"  
  27.             android:layout_toRightOf="@+id/tv_netease_top"  
  28.             android:text="@string/news_top_left_text2"  
  29.             android:textColor="@android:color/white"  
  30.             android:textSize="20sp" />  
  31.   
  32.         <ImageView  
  33.             android:layout_width="wrap_content"  
  34.             android:layout_height="wrap_content"  
  35.             android:layout_alignParentRight="true"  
  36.             android:src="@drawable/duoyun"  
  37.             android:contentDescription="@string/img_duoyun_desc" />  
  38.           
  39.     </RelativeLayout>  
  40.   
  41.     <RelativeLayout  
  42.         android:id="@+id/layout_title_bar"  
  43.         android:layout_width="fill_parent"  
  44.         android:layout_height="40dip"  
  45.         android:paddingLeft="5dip"  
  46.         android:paddingRight="5dip"  
  47.         android:background="@drawable/bg_header_top">  
  48.   
  49.         <LinearLayout  
  50.             android:id="@+id/header_item"  
  51.             android:layout_width="fill_parent"  
  52.             android:layout_height="match_parent"  
  53.             android:orientation="horizontal" >  
  54.   
  55.             <RelativeLayout  
  56.                 android:id="@+id/layout"  
  57.                 android:layout_width="match_parent"  
  58.                 android:layout_height="match_parent"  
  59.                 android:layout_weight="1" >  
  60.   
  61.                 <TextView  
  62.                     android:id="@+id/tv_title_news"  
  63.                     android:layout_width="match_parent"  
  64.                     android:layout_height="match_parent"  
  65.                     android:layout_centerInParent="true"  
  66.                     style="@style/header_title_style"  
  67.                     android:gravity="center"  
  68.                     android:text="@string/title_news_category_tops" />  
  69.                   
  70.             </RelativeLayout>  
  71.   
  72.             <RelativeLayout  
  73.                 android:layout_width="match_parent"  
  74.                 android:layout_height="match_parent"  
  75.                 android:layout_weight="1" >  
  76.   
  77.                 <TextView  
  78.                     android:id="@+id/tv_title_info"  
  79.                     android:layout_width="match_parent"  
  80.                     android:layout_height="match_parent"  
  81.                     android:layout_centerInParent="true"  
  82.                     style="@style/header_title_style"  
  83.                     android:gravity="center"  
  84.                     android:text="@string/title_news_category_info" />  
  85.                   
  86.             </RelativeLayout>  
  87.   
  88.             <RelativeLayout  
  89.                 android:layout_width="match_parent"  
  90.                 android:layout_height="match_parent"  
  91.                 android:layout_weight="1" >  
  92.   
  93.                 <TextView  
  94.                     android:id="@+id/tv_title_blog"  
  95.                     android:layout_width="match_parent"  
  96.                     android:layout_height="match_parent"  
  97.                     android:layout_centerInParent="true"  
  98.                     style="@style/header_title_style"  
  99.                     android:gravity="center"  
  100.                     android:text="@string/title_news_category_blog" />  
  101.                   
  102.             </RelativeLayout>  
  103.   
  104.             <RelativeLayout  
  105.                 android:layout_width="match_parent"  
  106.                 android:layout_height="match_parent"  
  107.                 android:layout_weight="1" >  
  108.   
  109.                 <TextView  
  110.                     android:id="@+id/tv_title_magazine"  
  111.                     android:layout_width="match_parent"  
  112.                     android:layout_height="match_parent"  
  113.                     android:layout_centerInParent="true"  
  114.                     style="@style/header_title_style"  
  115.                     android:gravity="center"  
  116.                     android:text="@string/title_news_category_magazine" />  
  117.                   
  118.             </RelativeLayout>  
  119.   
  120.             <RelativeLayout  
  121.                 android:layout_width="match_parent"  
  122.                 android:layout_height="match_parent"  
  123.                 android:layout_weight="1" >  
  124.   
  125.                 <TextView  
  126.                     android:id="@+id/tv_title_domain"  
  127.                     android:layout_width="match_parent"  
  128.                     android:layout_height="match_parent"  
  129.                     android:layout_centerInParent="true"  
  130.                     style="@style/header_title_style"  
  131.                     android:gravity="center"  
  132.                     android:text="@string/title_news_category_domain" />  
  133.                   
  134.             </RelativeLayout>  
  135.   
  136.             <RelativeLayout  
  137.                 android:layout_width="match_parent"  
  138.                 android:layout_height="match_parent"  
  139.                 android:layout_weight="1" >  
  140.   
  141.                 <TextView  
  142.                     android:id="@+id/tv_title_more"  
  143.                     android:layout_width="match_parent"  
  144.                     android:layout_height="match_parent"  
  145.                     android:layout_centerInParent="true"  
  146.                     style="@style/header_title_style"  
  147.                     android:gravity="center"  
  148.                     android:text="@string/title_news_category_more" />  
  149.             </RelativeLayout>  
  150.         </LinearLayout>  
  151.     </RelativeLayout>  
  152. </LinearLayout>  

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

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

  1. mSelectedItem.setWidth((getScreenWidth() - DimensionUtility.dip2px(this20)) / 6);  

用到了getScreenWidth方法:

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

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

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

  1. // 新闻分类事件监听  
  2.     @Override  
  3.     public void onClick(View v) {  
  4.         mItemWidth = findViewById(R.id.layout).getWidth();  
  5.           
  6.         switch (v.getId()) {  
  7.         case R.id.tv_title_news:  
  8.             //动画滑动  
  9.             ImageAnimation.SetImageSlide(mSelectedItem, startX, 000);  
  10.             //设置滑动后动画开始位置  
  11.             startX = 0;  
  12.             //设置选中项显示文字,也就是高亮部分文字  
  13.             mSelectedItem.setText(R.string.title_news_category_tops);  
  14.             //设置左上角提示文字  
  15.             mNetEaseTop.setText(R.string.title_news_category_tops);  
  16.               
  17.             // 显示头条信息  
  18.             mIntent.setClass(MainActivity.this, TopicNews.class);  
  19.             mNewsMain = getLocalActivityManager().startActivity(  
  20.                     "TopicNews", mIntent).getDecorView();  
  21.             break;  
  22.         case R.id.tv_title_info:  
  23.             ImageAnimation.SetImageSlide(mSelectedItem, startX, mItemWidth, 00);  
  24.             startX = mItemWidth;  
  25.             mSelectedItem.setText(R.string.title_news_category_info);  
  26.             mNetEaseTop.setText(R.string.title_news_category_info);  
  27.               
  28.             // 显示资讯信息  
  29.             mIntent.setClass(MainActivity.this, InfoNews.class);  
  30.             mNewsMain = getLocalActivityManager().startActivity(  
  31.                     "InfoNews", mIntent).getDecorView();  
  32.             break;  
  33.         case R.id.tv_title_blog:  
  34.             ImageAnimation.SetImageSlide(mSelectedItem, startX, mItemWidth * 200);  
  35.             startX = mItemWidth * 2;  
  36.             mSelectedItem.setText(R.string.title_news_category_blog);  
  37.             mNetEaseTop.setText(R.string.title_news_category_blog);  
  38.               
  39.             // 显示博客信息  
  40.             mIntent.setClass(MainActivity.this, BlogNews.class);  
  41.             mNewsMain = getLocalActivityManager().startActivity(  
  42.                     "BlogNews", mIntent).getDecorView();  
  43.             break;  
  44.         case R.id.tv_title_magazine:  
  45.             ImageAnimation.SetImageSlide(mSelectedItem, startX, mItemWidth * 300);  
  46.             startX = mItemWidth * 3;  
  47.             mSelectedItem.setText(R.string.title_news_category_magazine);  
  48.             mNetEaseTop.setText(R.string.title_news_category_magazine);  
  49.               
  50.             // 显示杂志信息  
  51.             mIntent.setClass(MainActivity.this, MagazineNews.class);  
  52.             mNewsMain = getLocalActivityManager().startActivity(  
  53.                     "MagazineNews", mIntent).getDecorView();  
  54.             break;  
  55.         case R.id.tv_title_domain:  
  56.             ImageAnimation.SetImageSlide(mSelectedItem, startX, mItemWidth * 400);  
  57.             startX = mItemWidth * 4;  
  58.             mSelectedItem.setText(R.string.title_news_category_domain);  
  59.             mNetEaseTop.setText(R.string.title_news_category_domain);  
  60.             // 显示业界信息  
  61.             mIntent.setClass(MainActivity.this, DomainNews.class);  
  62.             mNewsMain = getLocalActivityManager().startActivity(  
  63.                     "DomainNews", mIntent).getDecorView();  
  64.             break;  
  65.         case R.id.tv_title_more:  
  66.             ImageAnimation.SetImageSlide(mSelectedItem, startX, mItemWidth * 500);  
  67.             startX = mItemWidth * 5;  
  68.             mSelectedItem.setText(R.string.title_news_category_more);  
  69.             mNetEaseTop.setText(R.string.title_news_category_more);  
  70.               
  71.             // 显示更多信息  
  72.             mIntent.setClass(MainActivity.this, MoreNews.class);  
  73.             mNewsMain = getLocalActivityManager().startActivity(  
  74.                     "MoreNews", mIntent).getDecorView();  
  75.             break;  
  76.         default:  
  77.             break;  
  78.         }         
  79.         // 更换Layout中的新闻主体  
  80.         mNewsMainLayout.removeAllViews();  
  81.         mNewsMainLayout.addView(mNewsMain, params);  
  82.     }  

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

抱歉!评论已关闭.