仿網易新聞效果原始碼分析

傲慢的上校發表於2012-11-08

一直想知道這種效果到底是如何做出來的,直到看到程式碼,原來還是動畫。從網上找了兩份程式碼,原理基本相同,兩份程式碼中應該有相互參考部分,現在簡單解析下,做一個記錄,另外,程式碼中做了些許不妨礙功能的修改(如果有時間的話,自己也會考慮用fragment實現下)。先看下效果圖:


這裡主要講解的是以下部分:


先看下注釋裡面的說明:

/**
 * Android實現區域性圖片滑動指引效果
 * @Description: 實現以下功能:
 * 1、頂部單張圖片左右拖拉滑動;
 * 2、帶指引;
 * 3、僅滑動頂部單張圖片,不滑動頁面,下面的圖文內容不動; 
 * 4、類似於新聞客戶端的功能


看下它的主Activity裡面的全域性變數(也就是上面圖形):

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重新實現一下。

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


再看onCreate方法:

@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是指的


這一塊內容,在原始碼中,作者並未做這一塊和下面內容的同時更新,個人後來加上。設定頭條新聞主題下面就是設定預設選擇項:第一項(頭條新聞)。

再來看一下里面用到的佈局檔案:

<?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:

<?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>

比較簡單的佈局,不詳述。

上面程式碼設定選中項寬頻:

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

用到了getScreenWidth方法:

/**
     * 獲取螢幕的寬度
     * @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。可以使用註釋掉的程式碼獲取螢幕寬度。

下面是最重要的部分點選切換:

// 新聞分類事件監聽
	@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:

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中,先看下使用到的全域性變數:

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方法:

	@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());
	}

看一下遠點圖片區域:

// 圓點圖片區域
		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方法:

public int[] getSlideImages(){
		return slideImages;
	}
這裡的slideImage是在類中定義好的:

// 滑動圖片的集合,這裡設定成了固定載入,當然也可動態載入。
	private int[] slideImages = {
			R.drawable.image01,
			R.drawable.image02,
			R.drawable.image03,
			R.drawable.image04,
			R.drawable.image05};
那看一下用到的SlideImageLayout類的getSlideImageLayout:獲取圖片的佈局:

/**
	 * 生成滑動圖片區域佈局
	 * @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:


 * 設定圓點個數
	 * @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中還有設定滑動圖片標題:


// 設定預設的滑動標題
		mSlideTitle = (TextView) mMainView.findViewById(R.id.tvSlideTitle);
		mSlideTitle.setText(mParser.getSlideTitles()[0]);
		
		setContentView(mMainView);

最後是設定Viewpager的Adapter還有監聽

// 設定ViewPager
        mViewPager.setAdapter(new SlideImageAdapter());  
        mViewPager.setOnPageChangeListener(new ImagePageChangeListener());

先來看下SlideImageAdapter類:

// 滑動圖片資料介面卡
    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) {  
        }  
    }

一個典型的介面卡類,主要看下面兩個方法:

@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中去。

其實他的滑動監聽事件特別簡單,就是改變下選中圖片、標識圓點和標題文字:

// 滑動頁面更改事件監聽器
    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);  
                }  
            }
        }  
    }


還有,在網易新聞裡,有個底部標記欄:


這個功能是如何實現的呢?


<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圖片:

<?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>

切換程式碼:

@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


相關文章