<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## (一).前言: 仿36Kr客戶端開發過程中,因為他們網站上面的新聞文章分類比較多,所以我這邊還是打算模仿網易新聞APP的主界面新聞標簽Tab以及頁面滑動效果來進行實現。要實現的頂部的Tab標簽的效果有很多方法例如采用開源項目ViewPagerIndicator中的TabPageIndicator就可以實現,不過查看了源碼發現該控件其實就是繼承自HorizontalScrollView自定義出來的。那既然這樣我這邊就準備帶著大家直接使用HorizontalScrollView來實現頂部tab標簽效果。底部的頁面滑動直接采用Fragment+ViewPager+FragmentStatePagerAdapter實現即可。后面我也會更新一篇直接使用ViewPagerIndicator開源控件實現tab標簽效果的文章,敬請期待~ 本例子具體代碼已經上傳到下面的項目中,歡迎各位去star和fork一下。 FastDev4Android框架項目地址:[https://github.com/jiangqqlmj/FastDev4Android](https://github.com/jiangqqlmj/FastDev4Android) ## (二).實現原理: ![](https://box.kancloud.cn/2016-01-18_569c8ec65ef12.jpg) 上面我這邊直接貼了36Kr官方APP的主界面頂部Tab標簽,我這邊直接模仿這個做。首先看上面截圖紅色框起來的部分,這邊的Tab是可以橫向滑動的那可以采用HorizontalScrollView控件實現,并且里邊的每一項Tab?Item都是可以進行添加和點擊。我們直接往HorizontalScrollView?addView子控件即可。Tab下面是若干個新聞文章列表的頁面且可以進行左右滑動可以采用ViewPager實現,每個頁面采用Fragment實現。 ![](https://box.kancloud.cn/2016-01-18_569c8ec678eab.jpg) 上圖是具體控件的分布和嵌套,下面我們來看一下具體實現: ## (三).具體實現: 3.1.首先我們需要有一個繼承自FragmentActivity的MainInfoActivity,該用來承載Fragment,該Activity中實現基本沒有啥代碼,就不貼詳細到時候去FastDev4Android項目中下載即可,這邊我們看一下Activity的布局文件: ~~~ <?xmlversion="1.0" encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical"android:layout_width="match_parent" android:layout_height="match_parent" > <includelayout="@layout/common_top_bar_layout"/> <fragment android:id="@+id/info_fragment" class="com.chinaztt.fda.fragment.InfoFragment" android:layout_width="fill_parent" android:layout_height="fill_parent" tools:layout="@layout/info_fragment_layout" /> </LinearLayout> ~~~ 該布局文件中直接把承載的InfoFragment寫在里邊了,當我們Activity加載的時候該Fragment也被加載了。 3.2.接下來就是InfoFragment了,讓我們首先看下我這邊定義的布局文件: ~~~ <?xmlversion="1.0" encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical"android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white"> <!--橫向滑動的容器--> <HorizontalScrollView android:id="@+id/horizontal_info" android:layout_width="fill_parent" android:layout_height="wrap_content" android:scrollbars="none"> <!--裝入每一個Tab項容器--> <LinearLayout android:id="@+id/linearlayout_container" android:layout_width="fill_parent" android:layout_height="49dp" android:orientation="horizontal"> </LinearLayout> </HorizontalScrollView> <android.support.v4.view.ViewPager android:id="@+id/info_viewpager" android:layout_width="fill_parent" android:layout_height="fill_parent"/> </LinearLayout> ~~~ ???????????該布局中主要分為兩部分,第一部分就是HorizontalScrollView控件該用來實現橫向滑動,為標簽Tab的容器,我們可以往里邊動態的添加TabItem。第二部分為ViewPager控件該用來實現頁面的左右滑動,其中每一項Item為Fragment。以上關鍵控件已經定義好了,下面就是需要在InfoFragment中實現Tab效果了。 首先定義和初始化控件: ~~~ /** * 當前選擇的分類 */ private int mCurClassIndex=0; /** * 選擇的分類字體顏色 */ private int mColorSelected; /** * 非選擇的分類字體顏色 */ private int mColorUnSelected; /** * 水平滾動的Tab容器 */ private HorizontalScrollView mScrollBar; /** * 分類導航的容器 */ private ViewGroup mClassContainer; /** * 水平滾動X */ private int mScrollX=0; mScrollBar=(HorizontalScrollView)mView.findViewById(R.id.horizontal_info); mClassContainer=(ViewGroup)mView.findViewById(R.id.linearlayout_container); ~~~ 對于Tab Item的動態添加使用下面寫得方法addScrollView(): ~~~ /** * 動態添加頂部Tab滑動的標簽 * @param titles */ private void addScrollView(String[]titles){ LayoutInflater mLayoutInflater=LayoutInflater.from(FDApplication.getInstance()); final int count=titles.length; for(int i=0;i<count;i++){ final String title=titles[i]; final Viewview=mLayoutInflater.inflate(R.layout.horizontal_item_layout,null); final LinearLayout linearLayout=(LinearLayout)view.findViewById(R.id.horizontal_linearlayout_type); final ImageView img_type=(ImageView)view.findViewById(R.id.horizontal_img_type); final TextView type_name=(TextView)view.findViewById(R.id.horizontal_tv_type); type_name.setText(title); if(i==mCurClassIndex){ //已經選中 type_name.setTextColor(mColorSelected); img_type.setImageResource(R.drawable.bottom_line_blue); }else { //未選中 type_name.setTextColor(mColorUnSelected); img_type.setImageResource(R.drawable.bottom_line_gray); } final int index=i; //點擊頂部Tab標簽,動態設置下面的ViewPager頁面 view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //首先設置當前的Item為正常狀態 View currentItem=mClassContainer.getChildAt(mCurClassIndex); ((TextView)(currentItem.findViewById(R.id.horizontal_tv_type))).setTextColor(mColorUnSelected); ((ImageView)(currentItem.findViewById(R.id.horizontal_img_type))).setImageResource(R.drawable.bottom_line_gray); mCurClassIndex=index; //設置點擊狀態 img_type.setImageResource(R.drawable.bottom_line_blue); type_name.setTextColor(mColorSelected); //跳轉到指定的ViewPager info_viewpager.setCurrentItem(mCurClassIndex); } }); mClassContainer.addView(view); } } ~~~ 該方法傳入了標簽的數組,根據標簽的數量進行遍歷動態添加,主要步驟如下: * 加載每一項Tab Item的布局,并且獲取Item中的相關控件并且設置數據和資源文件 * 判斷當前是否選中項,對于選中和未選中設置不同的字體顏色和資源文件 * 給每一項Item添加點擊事件,用來切換ViewPager跳轉到具體每一項頁面(Fragment) * 最終每一項Tab Item加入到容器中 上面我們有講到,使用Fragment+ViewPager實現頁面滑動切換,那我們需要一個頁面的自定義適配器了,我這邊創建了CNKFixedPagerAdapter該類繼承自FragmengStatePagerAdaper具體實現代碼如下,比較簡單就不詳細講解了: ~~~ public class CNKFixedPagerAdapter extends FragmentStatePagerAdapter { private String[] titles; public void setTitles(String[] titles) { this.titles = titles; } private List<Fragment> fragments; public CNKFixedPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { return this.fragments.get(position); } @Override public int getCount() { return this.fragments.size(); } @Override public Object instantiateItem(ViewGroup container, int position) { Fragment fragment=null; try { fragment=(Fragment)super.instantiateItem(container,position); }catch (Exception e){ } return fragment; } @Override public void destroyItem(ViewGroup container, int position, Object object) { } public List<Fragment> getFragments(){ return fragments; } public void setFragments(List<Fragment> fragments) { this.fragments = fragments; } } ~~~ 然后我們實例化ViewPager以及自定義適配器和顯示的Fragment數據綁定即可: ~~~ fragments=new ArrayList<>(); for(int i=0;i<12;i++){ OneFragment oneFragment=new OneFragment(); Bundle bundle=new Bundle(); bundle.putString("extra",titles[i]); oneFragment.setArguments(bundle); fragments.add(oneFragment); } mPagerAdater=new CNKFixedPagerAdapter(getChildFragmentManager()); mPagerAdater.setTitles(titles); mPagerAdater.setFragments(fragments); info_viewpager.setAdapter(mPagerAdater); ~~~ 最后我們不要忘記有一點是:當我們的ViewPager頁面切換的時候我們需要實習改變頂部Tab?Item的選中情況以及字體顏色等。所以我們需要給ViewPager添加頁面切換監聽器OnPageChangeListener,然后在回調的onPageSelected()方法中重新設置一下Tab?Item的效果。 ~~~ info_viewpager.setOnPageChangeListener(this); ~~~ ~~~ //下面三個回調方法 分別是在ViewPager進行滑動的時候調用 @Override public void onPageScrolled(int position,float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { //首先設置當前的Item為正常狀態 View preView=mClassContainer.getChildAt(mCurClassIndex); ((TextView)(preView.findViewById(R.id.horizontal_tv_type))).setTextColor(mColorUnSelected); ((ImageView)(preView.findViewById(R.id.horizontal_img_type))).setImageResource(R.drawable.bottom_line_gray); mCurClassIndex=position; //設置當前為選中狀態 View currentItem=mClassContainer.getChildAt(mCurClassIndex); ((ImageView)(currentItem.findViewById(R.id.horizontal_img_type))).setImageResource(R.drawable.bottom_line_blue); ((TextView)(currentItem.findViewById(R.id.horizontal_tv_type))).setTextColor(mColorSelected); //這邊移動的距離 是經過計算粗略得出來的 mScrollX=currentItem.getLeft()-300; Log.d("zttjiangqq","mScrollX:" + mScrollX); mScrollBar.post(new Runnable() { @Override public void run() { mScrollBar.scrollTo(mScrollX,0); } }); } @Override public void onPageScrollStateChanged(int state) { } ~~~ 上面onPageSelected()方法中我們首先設置原先的Item的顏色為正常未選中狀態,然后設置當前的位置選中以及字體顏色改變,最后讓HorizontalScrollView平移到合適的位置即可: 3.3.以上我們的核心代碼已經講解完成了,下面我們看一下運行效果: ![](https://box.kancloud.cn/2016-01-18_569c8ec69e875.jpg) 3.4.為了大家方便閱讀代碼,我這邊把InfoFragment的全部代碼貼出來: ~~~ public class InfoFragment extends Fragment implements ViewPager.OnPageChangeListener{ private View mView; ViewPager info_viewpager; private List<Fragment> fragments; private CNKFixedPagerAdapter mPagerAdater; private String[] titles=new String[]{"全部","氪TV","O2O","新硬件","Fun!!","企業服務","Fit&Health","在線教育","互聯網金融","大公司","專欄","新產品"}; /** * 當前選擇的分類 */ private int mCurClassIndex=0; /** * 選擇的分類字體顏色 */ private int mColorSelected; /** * 非選擇的分類字體顏色 */ private int mColorUnSelected; /** * 水平滾動的Tab容器 */ private HorizontalScrollView mScrollBar; /** * 分類導航的容器 */ private ViewGroup mClassContainer; /** * 水平滾動X */ private int mScrollX=0; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if(mView==null){ mView=inflater.inflate(R.layout.info_fragment_layout,container,false); initViews(); initValidata(); } return mView; } /** * 初始化布局控件 */ private void initViews(){ info_viewpager=(ViewPager)mView.findViewById(R.id.info_viewpager); mScrollBar=(HorizontalScrollView)mView.findViewById(R.id.horizontal_info); mClassContainer=(ViewGroup)mView.findViewById(R.id.linearlayout_container); } private void initValidata(){ mColorSelected=FDApplication.getInstance().getResources().getColor(R.color.color_selected); mColorUnSelected=FDApplication.getInstance().getResources().getColor(R.color.color_unselected); //添加Tab標簽 addScrollView(titles); mScrollBar.post(new Runnable() { @Override public void run() { mScrollBar.scrollTo(mScrollX,0); } }); fragments=new ArrayList<>(); for(int i=0;i<12;i++){ OneFragment oneFragment=new OneFragment(); Bundle bundle=new Bundle(); bundle.putString("extra",titles[i]); oneFragment.setArguments(bundle); fragments.add(oneFragment); } mPagerAdater=new CNKFixedPagerAdapter(getChildFragmentManager()); mPagerAdater.setTitles(titles); mPagerAdater.setFragments(fragments); info_viewpager.setAdapter(mPagerAdater); info_viewpager.setOnPageChangeListener(this); } /** * 動態添加頂部Tab滑動的標簽 * @param titles */ private void addScrollView(String[]titles){ LayoutInflater mLayoutInflater=LayoutInflater.from(FDApplication.getInstance()); final int count=titles.length; for(int i=0;i<count;i++){ final String title=titles[i]; final View view=mLayoutInflater.inflate(R.layout.horizontal_item_layout,null); final LinearLayout linearLayout=(LinearLayout)view.findViewById(R.id.horizontal_linearlayout_type); final ImageView img_type=(ImageView)view.findViewById(R.id.horizontal_img_type); final TextView type_name=(TextView)view.findViewById(R.id.horizontal_tv_type); type_name.setText(title); if(i==mCurClassIndex){ //已經選中 type_name.setTextColor(mColorSelected); img_type.setImageResource(R.drawable.bottom_line_blue); }else { //未選中 type_name.setTextColor(mColorUnSelected); img_type.setImageResource(R.drawable.bottom_line_gray); } final int index=i; //點擊頂部Tab標簽,動態設置下面的ViewPager頁面 view.setOnClickListener(newView.OnClickListener() { @Override public void onClick(View v) { //首先設置當前的Item為正常狀態 View currentItem=mClassContainer.getChildAt(mCurClassIndex); ((TextView)(currentItem.findViewById(R.id.horizontal_tv_type))).setTextColor(mColorUnSelected); ((ImageView)(currentItem.findViewById(R.id.horizontal_img_type))).setImageResource(R.drawable.bottom_line_gray); mCurClassIndex=index; //設置點擊狀態 img_type.setImageResource(R.drawable.bottom_line_blue); type_name.setTextColor(mColorSelected); //跳轉到指定的ViewPager info_viewpager.setCurrentItem(mCurClassIndex); } }); mClassContainer.addView(view); } } //下面三個回調方法 分別是在ViewPager進行滑動的時候調用 @Override public void onPageScrolled(int position,float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { //首先設置當前的Item為正常狀態 View preView=mClassContainer.getChildAt(mCurClassIndex); ((TextView)(preView.findViewById(R.id.horizontal_tv_type))).setTextColor(mColorUnSelected); ((ImageView)(preView.findViewById(R.id.horizontal_img_type))).setImageResource(R.drawable.bottom_line_gray); mCurClassIndex=position; //設置當前為選中狀態 View currentItem=mClassContainer.getChildAt(mCurClassIndex); ((ImageView)(currentItem.findViewById(R.id.horizontal_img_type))).setImageResource(R.drawable.bottom_line_blue); ((TextView)(currentItem.findViewById(R.id.horizontal_tv_type))).setTextColor(mColorSelected); //這邊移動的距離 是經過計算粗略得出來的 mScrollX=currentItem.getLeft()-300; Log.d("zttjiangqq","mScrollX:" + mScrollX); mScrollBar.post(new Runnable() { @Override public void run() { mScrollBar.scrollTo(mScrollX,0); } }); } @Override public void onPageScrollStateChanged(int state) { } } ~~~ ## (四).最后總結 今天我們通過Fragment+ViewPager+FragmentStatePagerAdapter+HorizontalScrollView實現了仿照網易新聞客戶端(或者36Kr)首頁的頁面滑動和頂部Tab效果。 本次實例代碼因為比較多,代碼全貼比較浪費篇幅,重點在于講解思路了。不過實例注釋過的全部代碼已經上傳到Github項目中了。同時歡迎大家去Github站點進行clone或者fork瀏覽整個開源快速開發框架項目~ [https://github.com/jiangqqlmj/FastDev4Android](https://github.com/jiangqqlmj/FastDev4Android)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看