Android利用Fragment實(shí)現(xiàn)Tab選項(xiàng)卡效果
利用Fragment實(shí)現(xiàn)Tab選項(xiàng)卡效果:
將RadioGroup與Fragment集合,實(shí)現(xiàn)tab選項(xiàng)卡效果,這里面最關(guān)鍵的幾個(gè)文件:
1.FragmentTabAdapter類(lèi):
/**
*@Description:
*@Author:Nate Robinson
*@Since:2015-2-12
*/
public class FragmentTabAdapter implements RadioGroup.OnCheckedChangeListener
{
private List<Fragment> fragments; // 一個(gè)tab頁(yè)面對(duì)應(yīng)一個(gè)Fragment
private RadioGroup rgs; // 用于切換tab
private Activity activity; // Fragment所屬的Activity
private int fragmentContentId; // Activity中所要被替換的區(qū)域的id
private int currentTab; // 當(dāng)前Tab頁(yè)面索引
private OnRgsExtraCheckedChangedListener onRgsExtraCheckedChangedListener; // 用于讓調(diào)用者在切換tab時(shí)候增加新的功能
public FragmentTabAdapter(Activity activity, List<Fragment> fragments, int fragmentContentId, RadioGroup rgs)
{
this.fragments = fragments;
this.rgs = rgs;
this.activity = activity;
this.fragmentContentId = fragmentContentId;
// 默認(rèn)顯示第一頁(yè)
android.app.FragmentTransaction ft = activity.getFragmentManager().beginTransaction();
ft.add(fragmentContentId, fragments.get(0));
ft.commit();
rgs.setOnCheckedChangeListener(this);
}
@Override
public void onCheckedChanged(RadioGroup radioGroup, int checkedId)
{
for(int i = 0; i < rgs.getChildCount(); i++)
{
if(rgs.getChildAt(i).getId() == (checkedId))
{
Fragment fragment = fragments.get(i);
FragmentTransaction ft = activity.getFragmentManager().beginTransaction();
getCurrentFragment().onPause(); // 暫停當(dāng)前tab
// getCurrentFragment().onStop(); // 暫停當(dāng)前tab
if(fragment.isAdded())
{
// fragment.onStart(); // 啟動(dòng)目標(biāo)tab的onStart()
fragment.onResume(); // 啟動(dòng)目標(biāo)tab的onResume()
}
else
{
ft.add(fragmentContentId, fragment);
}
showTab(i); // 顯示目標(biāo)tab
ft.commit();
// 如果設(shè)置了切換tab額外功能功能接口
if(null != onRgsExtraCheckedChangedListener)
{
onRgsExtraCheckedChangedListener.OnRgsExtraCheckedChanged(radioGroup, checkedId, i);
}
}
}
}
/**
* 切換tab
* @param idx
*/
private void showTab(int idx)
{
for(int i = 0; i < fragments.size(); i++)
{
Fragment fragment = fragments.get(i);
FragmentTransaction ft = activity.getFragmentManager().beginTransaction();
if(idx == i)
{
ft.show(fragment);
}
else
{
ft.hide(fragment);
}
ft.commit();
}
currentTab = idx; // 更新目標(biāo)tab為當(dāng)前tab
}
public int getCurrentTab()
{
return currentTab;
}
public Fragment getCurrentFragment()
{
return fragments.get(currentTab);
}
public OnRgsExtraCheckedChangedListener getOnRgsExtraCheckedChangedListener()
{
return onRgsExtraCheckedChangedListener;
}
public void setOnRgsExtraCheckedChangedListener(OnRgsExtraCheckedChangedListener onRgsExtraCheckedChangedListener)
{
this.onRgsExtraCheckedChangedListener = onRgsExtraCheckedChangedListener;
}
/**
* 切換tab額外功能功能接口
*/
public interface OnRgsExtraCheckedChangedListener
{
void OnRgsExtraCheckedChanged(RadioGroup radioGroup, int checkedId, int index);
}
}
2.activity_main.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="fill_parent" android:background="@android:color/white" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <FrameLayout android:id="@+id/tab_content" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1.0" android:background="#77557799" /> <RadioGroup android:id="@+id/tabs_rg" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:orientation="horizontal" android:paddingBottom="7dp" android:paddingTop="7dp" > <RadioButton android:id="@+id/tab_rb_a" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1.0" android:background="@drawable/selector_tab" android:button="@null" android:checked="true" android:drawableTop="@drawable/tablatestalert" android:gravity="center" android:singleLine="true" android:text="Tab1" android:textColor="#000000" android:textSize="13sp" /> <RadioButton android:id="@+id/tab_rb_b" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1.0" android:background="@drawable/selector_tab" android:button="@null" android:drawableTop="@drawable/tabsearch" android:gravity="center" android:singleLine="true" android:text="Tab2" android:textColor="#000000" android:textSize="13sp" /> <RadioButton android:id="@+id/tab_rb_c" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1.0" android:background="@drawable/selector_tab" android:button="@null" android:drawableTop="@drawable/tabrecommd" android:gravity="center" android:singleLine="true" android:text="Tab3" android:textColor="#000000" android:textSize="13sp" /> </RadioGroup> </LinearLayout> </LinearLayout>
3.MainActivity類(lèi):
/**
*@Description:
*@Author:Nate Robinson
*@Since:2015-2-12
*/
public class MainActivity extends Activity
{
private RadioGroup rgs;
private List<Fragment> fragments = new ArrayList<Fragment>();
private int index;
private static Boolean isExit = false;
private static Boolean hasTask = false;
private RadioButton button;
private Timer tExit = new Timer();
private TimerTask task = new TimerTask()
{
@Override
public void run()
{
isExit = false;
hasTask = true;
}
};
private FragmentTabAdapter tabAdapter;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragments.add(new FragmentOne());
fragments.add(new FragmentTwo());
fragments.add(new FragmentThree());
rgs = (RadioGroup) findViewById(R.id.tabs_rg);
button = (RadioButton) findViewById(R.id.tab_rb_a);
tabAdapter = new FragmentTabAdapter(this, fragments, R.id.tab_content, rgs);
tabAdapter.setOnRgsExtraCheckedChangedListener(new FragmentTabAdapter.OnRgsExtraCheckedChangedListener()
{
@Override
public void OnRgsExtraCheckedChanged(RadioGroup radioGroup, int checkedId, int index)
{
// 利用這個(gè)index可以實(shí)現(xiàn),如果不是在主頁(yè),按第一遍讓它先跳轉(zhuǎn)到第一個(gè)Fragment
System.out.println("Extra---- " + index + " checked!!! ");
MainActivity.this.index = index;
}
});
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if(keyCode == KeyEvent.KEYCODE_BACK)
{
if(index == 0)
{
if(isExit == false)
{
isExit = true;
Toast.makeText(MainActivity.this, "再按一次退出程序", Toast.LENGTH_SHORT).show();
if(!hasTask)
{
tExit.schedule(task, 1000);
}
}
else
{
finish();
System.exit(0);
}
}
else
{
// 如果不是在主頁(yè),按第一遍讓它先跳轉(zhuǎn)到第一個(gè)Fragment
// 利用上面的check方法會(huì)導(dǎo)致onCheckedChanged方法被執(zhí)行多次
// rgs.check(button.getId());
button.setChecked(true);
}
}
return false;
}
}
為了能同時(shí)學(xué)習(xí)Fragment生命周期,我在Fragment每個(gè)生命周期方法中加入了log打印,一個(gè)有三個(gè)這樣的Fragment,我只貼出其中一個(gè)代碼,其余和這個(gè)一樣:
/**
*@Description:
*@Author:Nate Robinson
*@Since:2015-2-12
*/
public class FragmentOne extends BaseFragment
{
private View view;
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
Log.d(TAG, "1==>FragmentOne=>onAttach");
}
@Override
public void onCreate(Bundle savedInstanceState)
{
Log.d(TAG, "2==>FragmentOne==>onCreate");
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
Log.d(TAG, "3==>FragmentOne==>onCreateView");
view = inflater.inflate(R.layout.fragment1, container, false);
TextView tv = (TextView) view.findViewById(R.id.tv);
tv.setText("FragmentOne");
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState)
{
Log.d(TAG, "4==>FragmentOne==>onActivityCreated");
super.onActivityCreated(savedInstanceState);
}
@Override
public void onStart()
{
Log.d(TAG, "5==>FragmentOne==>onStart");
super.onStart();
}
@Override
public void onResume()
{
Log.d(TAG, "6==>FragmentOne==>onResume");
super.onResume();
}
@Override
public void onPause()
{
Log.d(TAG, "7==>FragmentOne==>onPause");
super.onPause();
}
@Override
public void onStop()
{
Log.d(TAG, "8==>FragmentOne==>onStop");
super.onStop();
}
@Override
public void onDestroyView()
{
Log.d(TAG, "9==>FragmentOne==>onDestroyView");
super.onDestroyView();
}
@Override
public void onDestroy()
{
Log.d(TAG, "10==>FragmentOne==>onDestroy");
super.onDestroy();
}
@Override
public void onDetach()
{
Log.d(TAG, "11==>FragmentOne==>onDetach");
super.onDetach();
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
Log.d(TAG, "FragmentOne==>onViewCreated");
super.onViewCreated(view, savedInstanceState);
}
}
在編寫(xiě)過(guò)程中,我為了實(shí)現(xiàn)如果不是在主頁(yè),按第一遍讓它先跳轉(zhuǎn)到第一個(gè)Fragment這個(gè)效果,一開(kāi)始使用了rgs.check(button.getId());這個(gè)方法,結(jié)果發(fā)現(xiàn),這樣的話(huà)onCheckedChanged監(jiān)聽(tīng)事件會(huì)執(zhí)行兩次,后來(lái)改為button.setChecked(true);這個(gè)方法之后,成功解決了這個(gè)問(wèn)題。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android實(shí)現(xiàn)底部導(dǎo)航欄功能(選項(xiàng)卡)
- Android多個(gè)TAB選項(xiàng)卡切換效果
- Android仿微信底部實(shí)現(xiàn)Tab選項(xiàng)卡切換效果
- Android實(shí)現(xiàn)類(lèi)似網(wǎng)易新聞選項(xiàng)卡動(dòng)態(tài)滑動(dòng)效果
- Android編程實(shí)現(xiàn)自定義Tab選項(xiàng)卡功能示例
- Android編程實(shí)現(xiàn)將tab選項(xiàng)卡放在屏幕底部的方法
- Android開(kāi)發(fā)之選項(xiàng)卡功能的實(shí)現(xiàn)方法示例
- Android實(shí)現(xiàn)知乎選項(xiàng)卡動(dòng)態(tài)隱藏效果實(shí)例
相關(guān)文章
Android Parcelable與Serializable詳解及區(qū)別
這篇文章主要介紹了Android Parcelable與Serializable詳解及區(qū)別的相關(guān)資料,需要的朋友可以參考下2017-01-01
Android TextView實(shí)現(xiàn)垂直滾動(dòng)效果的方法
這篇文章主要介紹了Android TextView實(shí)現(xiàn)垂直滾動(dòng)效果的方法,結(jié)合實(shí)例形式簡(jiǎn)單分析了Android TextView控件垂直滾動(dòng)效果的相關(guān)屬性功能與設(shè)置技巧,需要的朋友可以參考下2016-10-10
Android筆記之:App調(diào)試的幾個(gè)命令的實(shí)踐與分析
本篇文章介紹了,在Android中:App調(diào)試的幾個(gè)命令的實(shí)踐與分析。需要的朋友參考下2013-04-04
Android?Camera開(kāi)發(fā)實(shí)現(xiàn)可復(fù)用的相機(jī)組件
這篇文章主要為大家詳細(xì)介紹了Android?Camera開(kāi)發(fā)實(shí)現(xiàn)可復(fù)用的相機(jī)組件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
Android無(wú)障礙自動(dòng)化結(jié)合opencv實(shí)現(xiàn)支付寶能量自動(dòng)收集操作方法
opencv可以進(jìn)行圖像識(shí)別,兩者結(jié)合在一起即可實(shí)現(xiàn)支付寶能量自動(dòng)收集,opencv用于識(shí)別能量,無(wú)障礙服務(wù)用于模擬手勢(shì),即點(diǎn)擊能量,這篇文章主要介紹了Android無(wú)障礙自動(dòng)化結(jié)合opencv實(shí)現(xiàn)支付寶能量自動(dòng)收集,需要的朋友可以參考下2024-07-07
Android實(shí)現(xiàn)系統(tǒng)級(jí)懸浮按鈕
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)系統(tǒng)級(jí)懸浮按鈕的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03
Android開(kāi)發(fā)之如何自定義數(shù)字鍵盤(pán)詳解
這篇文章主要給大家介紹了關(guān)于Android開(kāi)發(fā)之如何自定義數(shù)字鍵盤(pán)的相關(guān)資料,本文語(yǔ)言是基于kotlin實(shí)現(xiàn)的,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-09-09
Android Jetpack Compose實(shí)現(xiàn)列表吸頂效果
安卓傳統(tǒng)的Recyclerview打造懸浮頭部StickyHeader的吸頂效果,十分麻煩,而在Compose中就簡(jiǎn)單多了。因此,本文將采用Jetpack Compose實(shí)現(xiàn)列表吸頂效果,需要的可以參考一下2022-02-02

