最近學習到了viewpager的使用,利用fragment+viewpager+radioButton組合進行了一個導航菜單加界面的開發,再次分享一下,自己也算是複習一下。
首先建立一個工程,我現在的這個sdk的版本,建立工程預設建立一個activity,使用的是fragment實作,用着不太習慣,我一般會修改為原來的模式,一個activity,加載一個layout作為主界面,然後删掉多餘的代碼,運作一下,主界面出來了:

然後我們在界面布局檔案中區調textview,,放一個viewpager的元件,鋪滿全螢幕:
<android.support.v4.view.ViewPager
android:id="@+id/mViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
建立三個布局檔案,很簡單的就行,分别有一個按鈕,作為我們viewpager裡面的界面元素,這裡就不列出來了。
接下來建立三個fragment的類,繼承自v4的Fragment,并重寫其onCreateView方法,初始化将每個Fragment的界面,下面列出其中一個代碼片段:
package com.example.fragmentviewpager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class FragmentOne extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_page1, container,false);
return view;
}
}
接下來就要在activity中去初始化viewpager啦,先執行個體化viewpager對象,拿到我們的控件,并初始化Fragment數組,
private ViewPager viewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager)findViewById(R.id.mViewPager);
Fragment fragmentOne = new FragmentOne();
Fragment fragmentTwo = new FragmentTwo();
Fragment fragmentThree = new FragmentThree();
fragments = new Fragment[]{fragmentOne,fragmentTwo,fragmentThree};
}
然後我們就要給它設定擴充卡,還沒有,我們建立一個擴充卡類,繼承自FragmentPagerAdapter,然後重寫父類的抽象法方法,重寫構造方法,構造資料源,可以直接寫在activity中,作為内部類:
class MyViewPagerAdapter extends FragmentPagerAdapter{
public MyViewPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int index) {
return fragments[index];
}
@Override
public int getCount() {
return fragments.length;
}
}
接下來在onCreate方法中初始化我們的adapter,給viewpager設定上:
MyViewPagerAdapter adapter = new MyViewPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
運作一下,我們的viewpager+fragment就出現啦!fragment的好處就是可以與activity進行分離,傳統的方式需要在activity中加載所有視圖并初始化各種操作,造成activity代碼雜亂。
接下來我們就要開始添加标題,上下都可以,我把它放在上面, 标題欄放幾個textView,設定其點選事件,并高亮目前選中頁就可以,我采用radiobutton的方式,來進行切換。
我們現在viewpager元件上面添加一個radiogroup,裡面我們通過動态的方式建立radioButton,這樣添加一頁的布局檔案不需要修改:
<RadioGroup
android:id="@+id/radioGroup"
android:layout_width="match_parent"
android:layout_height="38dip"
android:layout_alignParentTop="true"
android:background="#000000"
android:orientation="horizontal" />
然後我們建立一個radiobutton的布局檔案nav_radiogroup_item.xml,設定一下radiobutton的樣式,
<?xml version="1.0" encoding="utf-8"?>
<RadioButton xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="0dip"
android:layout_height="fill_parent"
android:background="@drawable/rb_fouce_bg"
android:button="@null"
android:checked="false"
android:gravity="center"
android:text=""
android:textColor="@drawable/rb_blue_bg"
android:textSize="14.0dip" />
可以看到radiobutton的樣式中,背景和文字顯示都使用了drawable的方式,使用了兩個selector,處理單擊以及選中時背景和文字的交替變化,兩個selector檔案如下:
rb_blue_bg.xml處理文字顔色
<?xml version="1.0" encoding="UTF-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:color="#5AB0EB" />
<item android:state_checked="false" android:color="#ffffff"/>
</selector>
rb_fouce_bg.xml處理背景顔色
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:drawable="@color/blue"/>
<item android:drawable="@color/translate"></item>
</selector>
在背景顔色處理是用到了color資源,在我們的colors.xml中定義需要的顔色:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="blue">#99FFFF</color>
<color name="translate">#000000</color>
<color name="black">#000000</color>
<color name="white">#ffffff</color>
<color name="green">#ff0000</color>
<color name="red">#00ffff</color>
</resources>
接下來處理标題資源檔案,我們解除安裝arrays.xml裡面,友善配置:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="titles">
<item >頁面1</item>
<item >頁面2</item>
<item >頁面3</item>
</string-array>
</resources>
資源檔案處理完畢,現在開始代碼處理,在activity中初始化radiogroup以及我們的标題數組:
radioGroup = (RadioGroup)findViewById(R.id.radioGroup);
titles = getResources().getStringArray(R.array.titles);
接下來動态建立radiobutton添加到radiogroup中去,需要計算一下每個按鈕的寬度:
//計算每個标題的寬度
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics dm = new DisplayMetrics();
display.getMetrics(dm);
titleWidth = dm.widthPixels / titles.length;
//動态添加radiobutton
RadioButton rb = null;
radioGroup.removeAllViews();
LayoutInflater inflater = LayoutInflater.from(this);
for (int i = 0; i < titles.length; i++) {
//從布局中讀取單選按鈕布局
rb = (RadioButton)inflater.inflate(R.layout.nav_radiogroup_item, null);
//設定顯示文字
rb.setText(titles[i]);
//設定id。不能丢,區分用
rb.setId(i);
rb.setLayoutParams(new LayoutParams(titleWidth,LayoutParams.MATCH_PARENT));
if (i == 0) {
rb.setChecked(true);
}
radioGroup.addView(rb);
}
運作一下,我們的标題出來了:
但是和viewpager還不同步,下面開始寫單選按鈕時間和viewpager的選擇事件:
//單選按鈕事件
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
//選中時viewpager關聯
viewPager.setCurrentItem(checkedId);
}
});
//viewpager選中事件
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int index) {
//選中時模拟單選按鈕的單擊事件
((RadioButton)radioGroup.getChildAt(index)).performClick();
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
<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">
<RadioGroup
android:id="@+id/radioGroup"
android:layout_width="match_parent"
android:layout_height="38dip"
android:layout_alignParentTop="true"
android:background="#000000"
android:orientation="horizontal" />
<ImageView
android:id="@+id/splitImage"
android:layout_below="@id/radioGroup"
android:layout_width="5dip"
android:layout_height="5dip"
android:background="#5AB0EB"
android:scaleType="matrix"/>
<android.support.v4.view.ViewPager
android:layout_below="@id/splitImage"
android:id="@+id/mViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
splitImage = (ImageView)findViewById(R.id.splitImage);
LayoutParams layoutParams = splitImage.getLayoutParams();
layoutParams.width = titleWidth;
修改單選按鈕單擊事件,增加imageView的動畫效果:
//單選按鈕事件
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
//選中時viewpager關聯
viewPager.setCurrentItem(checkedId);
View radioButton = group.getChildAt(checkedId);
//建立位移動畫,從目前位置移動到新位置
Animation animation = new TranslateAnimation(splitImageLeft, radioButton.getLeft(), 0f, 0f);
animation.setDuration(300);
animation.setFillAfter(true);
splitImage.startAnimation(animation);
//記錄目前位置
splitImageLeft = radioButton.getLeft();
}
});
運作效果,差不多了: