第二種主界面風格則是以網易新聞、鳳凰新聞以及新推出的新浪博客(閱讀版)爲表明,使用ViewPager+Fragment,即ViewPager裏適配器裏放的不是通常的View,而是Fragment。因此適配器不能繼承PagerAdapter,而要繼承FragmentPagerAdapter,這是在android.support.v4.app.FragmentPagerAdapter包裏的。有點奇葩的是,FragmentPagerAdapter只在這個包裏有,在android.app.*這個包下面麼有。到後面會發現,只能用android.support.v4.app.*包下面的東西。兩個包裏的FragmentManager是不通用的,並且兩個包裏提供的Fragment也不大同樣。若是繼承android.app.*下的Fragment,則不能從新寫構造函數,只能用默認的。v4的包裏麼有這個限制。html
下圖是網易新聞、鳳凰新聞、新浪博客的截圖:java
關於仿網易新聞客戶端代碼已經不少了,本人主要根據開源的這個CSDN客戶端的製做,準備一步步搞下。這本是一個大牛之做發在oschina上,參考連接裏分5步去實現。我看了它的代碼,是染在一塊兒的。好比要完這個導航不須要額外的三個包,而他的資源裏是弄一塊兒的。因此準備本身玩玩,順便記錄開發中的問題。android
第一步:最上面的導航欄
即有「網易新聞」四個大字這一欄。佈局文件head_title_panel.xml:git
- <span style="font-family:Comic Sans MS;font-size:18px;"><?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@color/light_blue"
- android:orientation="horizontal" >
-
- <ImageView
- android:id="@+id/headIcon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:layout_marginLeft="8dp"
- android:layout_marginRight="4dp"
- android:src="@drawable/biz_navigation_tab_news_pressed" />
-
- <ImageView
- android:id="@+id/headDivider"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:layout_marginLeft="4dp"
- android:layout_marginRight="4dp"
- android:src="@drawable/base_action_bar_back_divider" />
-
- <TextView
- android:id="@+id/headTV"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:layout_marginLeft="4dp"
- android:layout_weight="1"
- android:text="CSDN資訊"
- android:textColor="@color/white"
- android:textSize="21sp"
- android:textStyle="bold">
- </TextView>
-
-
- </LinearLayout></span>
爲了往後操做上的方便,我將它映射成一個HeadTitlePanel.java文件,能夠看到這種寫法跟上篇 上下panel的定義是有點區別的。github
- <span style="font-family:Comic Sans MS;font-size:18px;">package org.yanzi.ui;
-
- import org.yanzi.csdnproject.R;
-
- import android.content.Context;
- import android.util.AttributeSet;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.widget.ImageView;
- import android.widget.RelativeLayout;
- import android.widget.TextView;
-
- public class HeadTitlePanel extends RelativeLayout {
-
- private Context mContext;
- private TextView mHeadTV;
- private ImageView mHeadIcon;
- private ImageView mHeadDivider;
-
- public HeadTitlePanel(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- mContext = context;
- View parent = LayoutInflater.from(mContext).inflate(R.layout.head_title_panel, this, true);
- mHeadTV = (TextView) parent.findViewById(R.id.headTV);
- }
-
-
-
- }
- </span>
第二步:ViewPager的導航欄
這個原本我是準備本身封裝個的,網上也有用Radiobutton封裝的,考慮到它這個導航欄仍是不固定長度能夠滑動的,時間緣由暫時不封裝了,使用開源Android-ViewPagerIndicator-master.zip 這個包,這我的的github連接:https://github.com/JakeWharton 將其中的library文件夾更名ViewPagerIndicator_library導進來。這個裏面有好幾種Indicator,咱們主要用TabPageIndicator這個。app
第三步:MainActivity的佈局:ide
activity_main.xml函數
- <span style="font-family:Comic Sans MS;font-size:18px;"><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#eee"
- tools:context=".MainActivity" >
-
- <org.yanzi.ui.HeadTitlePanel
- android:id="@+id/head_title_panel"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentTop="true" />
-
- <com.viewpagerindicator.TabPageIndicator
- android:id="@+id/page_indicator"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_below="@id/head_title_panel"
- android:background="@color/transparentblue" />
-
- <android.support.v4.view.ViewPager
- android:id="@+id/view_pager"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_below="@id/page_indicator"
- />
-
- </RelativeLayout></span>
MainActivity.java佈局
- <span style="font-family:Comic Sans MS;font-size:18px;">package org.yanzi.csdnproject;
-
- import org.yanzi.viewpager.adapter.TabAdapter;
-
- import com.viewpagerindicator.TabPageIndicator;
-
- import android.os.Bundle;
- import android.app.Activity;
- import android.app.FragmentManager;
- import android.view.Menu;
- import android.support.v4.app.FragmentActivity;
- import android.support.v4.app.FragmentPagerAdapter;
- import android.support.v4.view.ViewPager;
-
- public class MainActivity extends FragmentActivity {
- private TabPageIndicator mPageIndicator;
- private ViewPager mViewPager;
- private FragmentPagerAdapter fragPagerAdapter;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- initUI();
-
- fragPagerAdapter = new TabAdapter(getSupportFragmentManager());
- mViewPager.setAdapter(fragPagerAdapter);
- mPageIndicator.setViewPager(mViewPager, 0);
-
-
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
-
- getMenuInflater().inflate(R.menu.main, menu);
- return true;
- }
- private void initUI(){
- mPageIndicator = (TabPageIndicator)findViewById(R.id.page_indicator);
- mViewPager = (ViewPager)findViewById(R.id.view_pager);
- }
-
- }
- </span>
出奇的簡單,比單純用Fragment還簡單,緣由是隻需把Fragment塞到適配器裏就ok了,適配器爲咱們作了Fragment的切換等工做,咱們能作的也就是在適配器裏new Fragment的時候判斷是否已存在。如下幾點須要注意:ui
一、在styles.xml裏它定義了樣式:
- <span style="font-family:Comic Sans MS;font-size:18px;"> <style name="MyTheme" parent="AppBaseTheme">
- <item name="vpiTabPageIndicatorStyle">@style/MyWidget.TabPageIndicator</item>
- <item name="android:windowBackground">@drawable/init_pic</item>
- <item name="android:windowNoTitle">true</item>
- <item name="android:animationDuration">5000</item>
- <item name="android:windowContentOverlay">@null</item>
- </style>
- <style name="MyWidget.TabPageIndicator" parent="Widget">
- <item name="android:gravity">center</item>
- <item name="android:background">@drawable/vpi__tab_indicator</item>
- <item name="android:paddingLeft">22dip</item>
- <item name="android:paddingRight">22dip</item>
- <item name="android:paddingTop">8dp</item>
- <item name="android:paddingBottom">8dp</item>
- <item name="android:textAppearance">@style/MyTextAppearance.TabPageIndicator</item>
- <item name="android:textSize">16sp</item>
- <item name="android:maxLines">1</item>
- </style>
-
- <style name="MyTextAppearance.TabPageIndicator" parent="Widget">
- <item name="android:textStyle">bold</item>
- <item name="android:textColor">@color/black</item>
- </style></span>
這個是依賴於導進去的包的。
二、它這裏用了android:windowBackground的屬性,因此app開啓瞬間會有圖片彈出,以後設置MainActivity的佈局背景爲android:background="#eee",又把圖片替換了。若是不設android:background="#eee" 會一直看到這個圖片不消失。
三、由於開篇講的緣由,MainActivity只能繼承自FragmentActivity。
第四步:MainFragment.java,此類繼承Fragment,且是android.support.v4.app.Fragment下的。
- <span style="font-family:Comic Sans MS;font-size:18px;">package org.yanzi.fragment;
-
- import org.yanzi.csdnproject.R;
-
- import android.os.Bundle;
- import android.support.v4.app.Fragment;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.TextView;
-
- public class MainFragment extends Fragment {
- private int mNewsType = 0;
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
-
- View v = inflater.inflate(R.layout.tab_item_fragment_main, null);
- TextView tip = (TextView) v.findViewById(R.id.id_tip);
- Bundle b = getArguments();
- String title = b.getString("TITLES");
- tip.setText(title);
- return v;
- }
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
-
- super.onActivityCreated(savedInstanceState);
- }
-
-
- }
- </span>
就是弄了一個佈局,而後從中取得參數並顯示。
第五步:ViewPager的適配器TabAdapter.java
- <span style="font-family:Comic Sans MS;font-size:18px;">package org.yanzi.viewpager.adapter;
-
- import org.yanzi.constant.Constant;
- import org.yanzi.fragment.MainFragment;
-
- import android.os.Bundle;
- import android.support.v4.app.Fragment;
- import android.support.v4.app.FragmentManager;
- import android.support.v4.app.FragmentPagerAdapter;
-
- public class TabAdapter extends FragmentPagerAdapter {
-
- public TabAdapter(FragmentManager fm) {
-
- super(fm);
-
- }
-
- @Override
- public Fragment getItem(int position) {
-
- MainFragment fragment = new MainFragment();
- Bundle b = new Bundle();
- String title = Constant.TITLES[position];
- b.putString("TITLES", title);
- fragment.setArguments(b);
- return fragment;
- }
-
- @Override
- public CharSequence getPageTitle(int position) {
-
- return Constant.TITLES[position];
- }
-
- @Override
- public int getCount() {
-
- return Constant.TITLES.length;
- }
-
- }
- </span>
主要是重寫getItem,在這裏實例化Fragment,同時設傳遞的參數。其實這裏能夠經過
- <span style="font-family:Comic Sans MS;font-size:18px;">FragmentManager</span>
按照Tag查找對應的Fragment是否存在,再進行實例化。
另外,getPageTitle這個接口必須重寫,其實看TabPageIndicator.java這個類的實現能夠發現,它須要傳進去一個ViewPager,而後得到適配器,從適配器裏獲得Title。由於用了這個開源包,不能再用ViewPager的setOnPageChangeListener接口,只能用mPageIndicator.setOnPageChangeListener(listener)進行監聽。
完畢,源碼連接:連接:http://pan.baidu.com/s/1bn4EFbp 密碼:dx4s
效果以下:
http://blog.csdn.net/yanzi1225627/article/details/31462007#comments