天天看點

(android高仿系列)今日頭條 --新聞閱讀器 (一)

設定歡迎界面的調整動畫,2秒 [java]  view plain  copy  

(android高仿系列)今日頭條 --新聞閱讀器 (一)
(android高仿系列)今日頭條 --新聞閱讀器 (一)
  1.   start_anima = new AlphaAnimation(0.3f, 1.0f);  
  2. start_anima.setDuration(2000);  
  3. view.startAnimation(start_anima);  
  4. start_anima.setAnimationListener(new AnimationListener() {  
  5.     @Override  
  6.     public void onAnimationStart(Animation animation) {  
  7.         // TODO Auto-generated method stub  
  8.     }  
  9.     @Override  
  10.     public void onAnimationRepeat(Animation animation) {  
  11.         // TODO Auto-generated method stub  
  12.     }  
  13.     @Override  
  14.     public void onAnimationEnd(Animation animation) {  
  15.         // TODO Auto-generated method stub  
  16.         redirectTo();//跳轉  
  17.     }  
  18. });  

之後便是主界面:

可以發現主界面上方的欄目欄是可以橫向拖動的,并且選擇。

(android高仿系列)今日頭條 --新聞閱讀器 (一)

下面就首先來實作上部欄目拖動這個效果:

大體思路結構圖:

(android高仿系列)今日頭條 --新聞閱讀器 (一)

整體的布局檔案是如下這樣:

[java]  view plain  copy  

(android高仿系列)今日頭條 --新聞閱讀器 (一)
(android高仿系列)今日頭條 --新聞閱讀器 (一)
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical" >  
  6.     <include layout="@layout/main_head" />  
  7.     <LinearLayout  
  8.         android:layout_width="match_parent"  
  9.         android:layout_height="40.0dip"  
  10.         android:background="#fff3f3f3"  
  11.         android:orientation="horizontal" >  
  12.         <RelativeLayout  
  13.             android:id="@+id/rl_column"  
  14.             android:layout_width="match_parent"  
  15.             android:layout_height="40.0dip"  
  16.             android:layout_weight="1.0" >  
  17.             <com.topnews.view.ColumnHorizontalScrollView  
  18.                 android:id="@+id/mColumnHorizontalScrollView"  
  19.                 android:layout_width="match_parent"  
  20.                 android:layout_height="40.0dip"  
  21.                 android:scrollbars="none" >  
  22.                 <LinearLayout  
  23.                     android:id="@+id/mRadioGroup_content"  
  24.                     android:layout_width="fill_parent"  
  25.                     android:layout_height="40.0dip"  
  26.                     android:layout_centerVertical="true"  
  27.                     android:gravity="center_vertical"  
  28.                     android:orientation="horizontal"  
  29.                     android:paddingLeft="10.0dip"  
  30.                     android:paddingRight="10.0dip" />  
  31.             </com.topnews.view.ColumnHorizontalScrollView>  
  32.             <ImageView  
  33.                 android:id="@+id/shade_left"  
  34.                 android:layout_width="10.0dip"  
  35.                 android:layout_height="40.0dip"  
  36.                 android:layout_alignParentLeft="true"  
  37.                 android:layout_centerVertical="true"  
  38.                 android:background="@drawable/channel_leftblock"  
  39.                 android:visibility="gone" />  
  40.             <ImageView  
  41.                 android:id="@+id/shade_right"  
  42.                 android:layout_width="10.0dip"  
  43.                 android:layout_height="40.0dip"  
  44.                 android:layout_alignParentRight="true"  
  45.                 android:layout_centerVertical="true"  
  46.                 android:background="@drawable/channel_rightblock"  
  47.                 android:visibility="visible" />  
  48.         </RelativeLayout>  
  49.         <LinearLayout  
  50.             android:id="@+id/ll_more_columns"  
  51.             android:layout_width="wrap_content"  
  52.             android:layout_height="40.0dip" >  
  53.             <ImageView  
  54.                 android:id="@+id/button_more_columns"  
  55.                 android:layout_width="40.0dip"  
  56.                 android:layout_height="40.0dip"  
  57.                 android:layout_gravity="center_vertical"  
  58.                 android:src="@drawable/channel_glide_day_bg" />  
  59.         </LinearLayout>  
  60.     </LinearLayout>  
  61.     <View  
  62.         android:id="@+id/category_line"  
  63.         android:layout_width="fill_parent"  
  64.         android:layout_height="0.5dip"  
  65.         android:background="#ffdddddd" />  
  66.     <android.support.v4.view.ViewPager  
  67.         android:id="@+id/mViewPager"  
  68.         android:layout_width="match_parent"  
  69.         android:layout_height="match_parent" />  
  70. </LinearLayout>  

由于發現HorizontalScrollView左右拖動的時候沒有那種陰影效果,是以在這裡,我們發現了頭條的資源檔案下有這麼2個檔案:

(android高仿系列)今日頭條 --新聞閱讀器 (一)

這個就是它在白天模式和黑夜模式下用的陰影圖檔。那我們可以采取重寫HorizontalScrollView來判斷滾動,如果滾動時候不是在最左邊,顯示左邊陰影,不是在最右邊,顯示右邊陰影。

[java]  view plain  copy  

(android高仿系列)今日頭條 --新聞閱讀器 (一)
(android高仿系列)今日頭條 --新聞閱讀器 (一)
  1. public class ColumnHorizontalScrollView extends HorizontalScrollView {  
  2.     private View ll_content;  
  3.     private View ll_more;  
  4.     private View rl_column;  
  5.     private ImageView leftImage;  
  6.     private ImageView rightImage;  
  7.     private int mScreenWitdh = 0;  
  8.     private Activity activity;  
  9.     public ColumnHorizontalScrollView(Context context) {  
  10.         super(context);  
  11.     }  
  12.     public ColumnHorizontalScrollView(Context context, AttributeSet attrs) {  
  13.         super(context, attrs);  
  14.     }  
  15.     public ColumnHorizontalScrollView(Context context, AttributeSet attrs,  
  16.             int defStyle) {  
  17.         super(context, attrs, defStyle);  
  18.     }  
  19.     @Override  
  20.     protected void onScrollChanged(int paramInt1, int paramInt2, int paramInt3, int paramInt4) {  
  21.         // TODO Auto-generated method stub  
  22.         super.onScrollChanged(paramInt1, paramInt2, paramInt3, paramInt4);  
  23.         shade_ShowOrHide();  
  24.         if(!activity.isFinishing() && ll_content !=null && leftImage!=null && rightImage!=null && ll_more!=null && rl_column !=null){  
  25.             if(ll_content.getWidth() <= mScreenWitdh){  
  26.                 leftImage.setVisibility(View.GONE);  
  27.                 rightImage.setVisibility(View.GONE);  
  28.             }  
  29.         }else{  
  30.             return;  
  31.         }  
  32.         if(paramInt1 ==0){  
  33.             leftImage.setVisibility(View.GONE);  
  34.             rightImage.setVisibility(View.VISIBLE);  
  35.             return;  
  36.         }  
  37.         if(ll_content.getWidth() - paramInt1 + ll_more.getWidth() + rl_column.getLeft() == mScreenWitdh){  
  38.             leftImage.setVisibility(View.VISIBLE);  
  39.             rightImage.setVisibility(View.GONE);  
  40.             return;  
  41.         }  
  42.         leftImage.setVisibility(View.VISIBLE);  
  43.        <span style="white-space:pre">   </span>rightImage.setVisibility(View.VISIBLE);  
  44.     }  
  45.     public void setParam(Activity activity, int mScreenWitdh,View paramView1,ImageView paramView2, ImageView paramView3 ,View paramView4,View paramView5){  
  46.         this.activity = activity;  
  47.         this.mScreenWitdh = mScreenWitdh;  
  48.         ll_content = paramView1;  
  49.         leftImage = paramView2;  
  50.         rightImage = paramView3;  
  51.         ll_more = paramView4;  
  52.         rl_column = paramView5;  
  53.     }  
  54.     public void shade_ShowOrHide() {  
  55.         if (!activity.isFinishing() && ll_content != null) {  
  56.             measure(0, 0);  
  57.             //如果整體寬度小于螢幕寬度的話,那左右陰影都隐藏  
  58.             if (mScreenWitdh >= getMeasuredWidth()) {  
  59.                 leftImage.setVisibility(View.GONE);  
  60.                 rightImage.setVisibility(View.GONE);  
  61.             }  
  62.         } else {  
  63.             return;  
  64.         }  
  65.         //如果滑動在最左邊時候,左邊陰影隐藏,右邊顯示  
  66.         if (getLeft() == 0) {  
  67.             leftImage.setVisibility(View.GONE);  
  68.             rightImage.setVisibility(View.VISIBLE);  
  69.             return;  
  70.         }  
  71.         //如果滑動在最右邊時候,左邊陰影顯示,右邊隐藏  
  72.         if (getRight() == getMeasuredWidth() - mScreenWitdh) {  
  73.             leftImage.setVisibility(View.VISIBLE);  
  74.             rightImage.setVisibility(View.GONE);  
  75.             return;  
  76.         }  
  77.         //否則,說明在中間位置,左、右陰影都顯示  
  78.         leftImage.setVisibility(View.VISIBLE);  
  79.         rightImage.setVisibility(View.VISIBLE);  
  80.     }  
  81. }  

之後

private ArrayList<NewsClassify> newsClassify=new ArrayList<NewsClassify>();

根據newsClassify這個欄目分類清單裡面的數量進行添加欄目。(這裡首先采用了自己限定的ITEM,而沒有進行資料庫的操作,以後加上)

ViewPage的擴充卡NewsFragmentPagerAdapter,通過ViewPage切換對應欄目的的Fragment:

[java]  view plain  copy  

(android高仿系列)今日頭條 --新聞閱讀器 (一)
(android高仿系列)今日頭條 --新聞閱讀器 (一)
  1. public class NewsFragmentPagerAdapter extends FragmentPagerAdapter {  
  2.     private ArrayList<Fragment> fragments;  
  3.     private FragmentManager fm;  
  4.     public NewsFragmentPagerAdapter(FragmentManager fm) {  
  5.         super(fm);  
  6.         this.fm = fm;  
  7.     }  
  8.     public NewsFragmentPagerAdapter(FragmentManager fm,  
  9.             ArrayList<Fragment> fragments) {  
  10.         super(fm);  
  11.         this.fm = fm;  
  12.         this.fragments = fragments;  
  13.     }  
  14.     @Override  
  15.     public int getCount() {  
  16.         return fragments.size();  
  17.     }  
  18.     @Override  
  19.     public Fragment getItem(int position) {  
  20.         return fragments.get(position);  
  21.     }  
  22.     @Override  
  23.     public int getItemPosition(Object object) {  
  24.         return POSITION_NONE;  
  25.     }  
  26.     public void setFragments(ArrayList<Fragment> fragments) {  
  27.         if (this.fragments != null) {  
  28.             FragmentTransaction ft = fm.beginTransaction();  
  29.             for (Fragment f : this.fragments) {  
  30.                 ft.remove(f);  
  31.             }  
  32.             ft.commit();  
  33.             ft = null;  
  34.             fm.executePendingTransactions();  
  35.         }  
  36.         this.fragments = fragments;  
  37.         notifyDataSetChanged();  
  38.     }  
  39.     @Override  
  40.     public Object instantiateItem(ViewGroup container, final int position) {  
  41.         Object obj = super.instantiateItem(container, position);  
  42.         return obj;  
  43.     }  
  44. }  

之後添加欄目ITEM:

[java]  view plain  copy  

(android高仿系列)今日頭條 --新聞閱讀器 (一)
(android高仿系列)今日頭條 --新聞閱讀器 (一)
  1. int count =  newsClassify.size();  
  2.     for(int i = 0; i< count; i++){  
  3.         LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(mItemWidth , LayoutParams.WRAP_CONTENT);  
  4.         params.leftMargin = 10;  
  5.         params.rightMargin = 10;  
  6.         TextView localTextView = new TextView(this);  
  7.         localTextView.setTextAppearance(this, R.style.top_category_scroll_view_item_text);  
  8.         localTextView.setBackgroundResource(R.drawable.radio_buttong_bg);  
  9.         localTextView.setGravity(Gravity.CENTER);  
  10.         localTextView.setPadding(5, 0, 5, 0);  
  11.         localTextView.setId(i);  
  12.         localTextView.setText(newsClassify.get(i).getTitle());  
  13.         localTextView.setTextColor(getResources().getColorStateList(R.color.top_category_scroll_text_color_day));  
  14.         if(columnSelectIndex == i){  
  15.             localTextView.setSelected(true);  
  16.         }  
  17.         localTextView.setOnClickListener(new OnClickListener() {  
  18.             @Override  
  19.             public void onClick(View v) {  
  20.                   for(int i = 0;i < mRadioGroup_content.getChildCount();i++){  
  21.                       View localView = mRadioGroup_content.getChildAt(i);  
  22.                       if (localView != v)  
  23.                           localView.setSelected(false);  
  24.                       else{  
  25.                           localView.setSelected(true);  
  26.                           mViewPager.setCurrentItem(i);  
  27.                       }  
  28.                   }  
  29.                   Toast.makeText(getApplicationContext(), newsClassify.get(v.getId()).getTitle(), Toast.LENGTH_SHORT).show();  
  30.             }  
  31.         });  
  32.         mRadioGroup_content.addView(localTextView, i ,params);  
  33.     }  

之後根據選擇欄目的來調整ColumnHorizontalScrollView中的位置

[java]  view plain  copy  

(android高仿系列)今日頭條 --新聞閱讀器 (一)
(android高仿系列)今日頭條 --新聞閱讀器 (一)
  1. <span style="white-space:pre">  </span>  
  2.     private void selectTab(int tab_postion) {  
  3.         columnSelectIndex = tab_postion;  
  4.         for (int i = 0; i < mRadioGroup_content.getChildCount(); i++) {  
  5.             View checkView = mRadioGroup_content.getChildAt(tab_postion);  
  6.             int k = checkView.getMeasuredWidth();  
  7.             int l = checkView.getLeft();  
  8.             int i2 = l + k / 2 - mScreenWidth / 2;  
  9.             // rg_nav_content.getParent()).smoothScrollTo(i2, 0);  
  10.             mColumnHorizontalScrollView.smoothScrollTo(i2, 0);  
  11.             // mColumnHorizontalScrollView.smoothScrollTo((position - 2) *  
  12.             // mItemWidth , 0);  
  13.         }  
  14.         //判斷是否選中  
  15.         for (int j = 0; j <  mRadioGroup_content.getChildCount(); j++) {  
  16.             View checkView = mRadioGroup_content.getChildAt(j);  
  17.             boolean ischeck;  
  18.             if (j == tab_postion) {  
  19.                 ischeck = true;  
  20.             } else {  
  21.                 ischeck = false;  
  22.             }  
  23.             checkView.setSelected(ischeck);  
  24.         }  
  25.     }  

完成的效果如下:

(android高仿系列)今日頭條 --新聞閱讀器 (一)

更多注釋和實作方法可以檢視DEMO源碼檔案,源碼下載下傳位址 :  DEMO源碼

繼續閱讀