Android App開發學習第二十二天:Fragment
1.基本概念
1)它是什麼鬼,有什麼用?
答:Fragment是Android3.0後引入的一個新的API,他出現的初衷是為了適應大螢幕的平板電腦, 當然現在他仍然是平板APP UI設計的寵兒,而且我們普通手機開發也會加入這個Fragment, 我們可以把他看成一個小型的Activity,又稱Activity片段!想想,如果一個很大的介面,我們 就一個佈局,寫起介面來會有多麻煩,而且如果元件多的話是管理起來也很麻煩!而使用Fragment 我們可以把螢幕劃分成幾塊,然後進行分組,進行一個模組化的管理!從而可以更加方便的在 執行過程中動態地更新Activity的使用者介面!另外Fragment並不能單獨使用,他需要巢狀在Activity 中使用,儘管他擁有自己的生命週期,但是還是會受到宿主Activity的生命週期的影響,比如Activity 被destory銷燬了,他也會跟著銷燬!
下圖是文件中給出的一個Fragment分別對應手機與平板間不同情況的處理圖:
PS:簡單的新聞瀏覽頁面,使用兩個Fragment分別顯示新聞列表與新聞內容;
2)Fragment的生命週期圖
3)核心要點:
下面說下使用Fragment的一些要點:
3.0版本後引入,即minSdk要大於11
Fragment需要巢狀在Activity中使用,當然也可以巢狀到另外一個Fragment中,但這個被巢狀 的Fragment也是需要巢狀在Activity中的,間接地說,Fragment還是需要巢狀在Activity中!! 受寄主Activity的生命週期影響,當然他也有自己的生命週期!另外不建議在Fragment裡面 巢狀Fragment因為巢狀在裡面的Fragment生命週期不可控!!!
官方文件說建立Fragment時至少需要實現三個方法:onCreate( ),onCreateView( ),OnPause( ); 不過貌似只寫一個onCreateView也是可以的…
Fragment的生命週期和Activity有點類似:三種狀態: Resumed:在允許中的Fragment可見 Paused:所在Activity可見,但是得不到焦點 Stoped: ①呼叫addToBackStack(),Fragment被新增到Bcak棧 ②該Activity轉向後臺,或者該Fragment被替換/刪除
ps:停止狀態的fragment仍然活著(所有狀態和成員資訊被系統保持著),然而,它對使用者 不再可見,並且如果activity被幹掉,他也會被幹掉.
4)Fragment的幾個子類:
ps:很多時候我們都是直接重寫Fragment,inflate載入佈局完成相應業務了,子類用的不多,等需要的 時候在深入研究!
對話方塊:DialogFragment
列表:ListFragment
選項設定:PreferenceFragment
WebView介面:WebViewFragment
建立Fragment
1)靜態載入Fragment
2)動態載入Fragment
實現流程:
3.Fragment管理與Fragment事務
4.Fragment與Activity的互動
可能有的朋友不喜歡看圖,接下來用文字介紹下吧:
1)元件獲取
Fragment獲得Activity中的元件: getActivity().findViewById(R.id.list);
Activity獲得Fragment中的元件(根據id和tag都可以):getFragmentManager.findFragmentByid(R.id.fragment1);
2)資料傳遞
①Activit傳遞資料給Fragment:
在Activity中建立Bundle資料包,呼叫Fragment例項的setArguments(bundle) 從而將Bundle資料包傳給Fragment,然後Fragment中呼叫getArguments獲得 Bundle物件,然後進行解析就可以了
②Fragment傳遞資料給Activity
在Fragment中定義一個內部回撥介面,再讓包含該Fragment的Activity實現該回撥介面, Fragment就可以通過回撥介面傳資料了,回撥,相信很多人都知道是什麼玩意,但是 寫不出來啊,網上的一百度"fragment傳資料給Activity",全是李剛老師的那個程式碼,真心無語 算了,這裡就寫下區域性程式碼吧,相信讀者一看就懂的了:
Step 1:定義一個回撥介面:(Fragment中)
/*介面*/
public interface CallBack{
/*定義一個獲取資訊的方法*/
public void getResult(String result);
}
Step 2:介面回撥(Fragment中)
/*介面回撥*/
public void getData(CallBack callBack){
/*獲取文字框的資訊,當然你也可以傳其他型別的引數,看需求咯*/
String msg = editText.getText().toString();
callBack.getResult(msg);
}
Step 3:使用介面回撥方法讀資料(Activity中)
/* 使用介面回撥的方法獲取資料 */
leftFragment.getData(new CallBack() {
@Override
public void getResult(String result) { /*列印資訊*/
Toast.makeText(MainActivity.this, "-->>" + result, 1).show();
}
});
總結下方法: ->在Fragment定義一個介面,介面中定義抽象方法,你要傳什麼型別的資料引數就設定為什麼型別;
->接著還有寫一個呼叫介面中的抽象方法,把要傳遞的資料傳過去
->再接著就是Activity了,呼叫Fragment提供的那個方法,然後重寫抽象方法的時候進行資料 的讀取就可以了!!!
③Fragment與Fragment之間的資料互傳
其實這很簡單,找到要接受資料的fragment物件,直接呼叫setArguments傳資料進去就可以了 通常的話是replace時,即fragment跳轉的時候傳資料的,那麼只需要在初始化要跳轉的Fragment 後呼叫他的setArguments方法傳入資料即可!
如果是兩個Fragment需要即時傳資料,而非跳轉的話,就需要先在Activity獲得f1傳過來的資料, 再傳到f2了,就是以Activity為媒介~
示例程式碼如下:
FragmentManager fManager = getSupportFragmentManager( );
FragmentTransaction fTransaction = fManager.beginTransaction();
Fragmentthree t1 = new Fragmentthree();
Fragmenttwo t2 = new Fragmenttwo();
Bundle bundle = new Bundle();
bundle.putString("key",id);
t2.setArguments(bundle);
fTransaction.add(R.id.fragmentRoot, t2, "~~~");
fTransaction.addToBackStack(t1);
fTransaction.commit();
5.走一次生命週期圖:
思前想後還是決定要帶大家簡單的走一趟生命週期圖,加深大家對Fragment生命週期的理解:
①Activity載入Fragment的時候,依次呼叫下面的方法: onAttach -> onCreate -> onCreateView -> onActivityCreated -> onStart ->onResume
②當我們弄出一個懸浮的對話方塊風格的Activity,或者其他,就是讓Fragment所在的Activity可見,但不獲得焦點 onPause
③當對話方塊關閉,Activity又獲得了焦點: onResume
④當我們替換Fragment,並呼叫addToBackStack()將他新增到Back棧中 onPause -> onStop -> onDestoryView !!注意,此時的Fragment還沒有被銷燬哦!!!
⑤當我們按下鍵盤的回退鍵,Fragment會再次顯示出來: onCreateView -> onActivityCreated -> onStart -> onResume
⑥如果我們替換後,在事務commit之前沒有呼叫addToBackStack()方法將 Fragment新增到back棧中的話;又或者退出了Activity的話,那麼Fragment將會被完全結束, Fragment會進入銷燬狀態 onPause -> onStop -> onDestoryView -> onDestory -> onDetach
新建一個類繼承Fragment並重寫onCreateView()方法,來為該fragment重設佈局檔案
public class ListFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_list,container,false);
return view;
}
}
在Activity中新增Fragment
1.直接在佈局檔案中新增Fragment
建立兩個Fragment,然後在Activity中使用<fragment 標籤將frament新增進去
<fragment
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:name="com.example.ListFragment"
android:id="@+id/list"
android:layout_weight="1"/>
<fragment
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:name="com.example.DetailFragment"
android:id="@+id/detail"
android:layout_weight="2"/>
2.當Activity執行時新增Fragment
FragmentManager fm = getFragmentManager();建立fragment管理器
FragmentTransaction fragmentTransaction = fm.beginTransaction();開啟事務
ft.add(android.R.id.content,detailFragment):新增fragment
ft…replace(R.id.fragment,Fragment):更新fragment
ft.commit();提交事務
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DetailFragment detailFragment = new DetailFragment();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(android.R.id.content,detailFragment);
ft.commit();
}
}
實現模擬微信介面中的Tab標籤切換功能
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment
android:id="@+id/fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.example.Wechat_Fragment"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:orientation="horizontal">
<ImageView
android:id="@+id/image1"
android:layout_width="1dp"
android:layout_height="50dp"
android:layout_weight="1"
android:src="@drawable/icon1"/>
<ImageView
android:id="@+id/image2"
android:layout_width="1dp"
android:layout_height="50dp"
android:layout_weight="1"
android:src="@drawable/icon2"/>
</LinearLayout>
</RelativeLayout>
MainActivity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView imageView1 = findViewById(R.id.image1);
ImageView imageView2 = findViewById(R.id.image2);
imageView1.setOnClickListener(l);
imageView2.setOnClickListener(l);
}
View.OnClickListener l= new View.OnClickListener(){
@Override
public void onClick(View v) {
//使用事務管理fragment的新增和更新
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
Fragment f= null;
//獲取要切換的fragment
switch (v.getId())
{
case R.id.image1:
f = new Wechat_Fragment();
break;
case R.id.image2:
f = new Message_Fragment();
break;
default:break;
}
fragmentTransaction.replace(R.id.fragment,f);
fragmentTransaction.commit();
}
};
}
底部導航欄+ViewPager滑動切換頁面
1.ViewPager簡單介紹
1)是怎麼樣的一個控制元件?
答:一個頁面切換的元件,我們可以往裡面填充多個View,然後我們可以通過觸控螢幕左右滑動 切換不同的View,和前面學習的ListView一樣,我們需要一個Adapter(介面卡),將要顯示的View和 我們的ViewPager進行繫結,而ViewPager有他自己特定的Adapter——PagerAdapter!另外,Google 官方是建議我們使用Fragment來填充ViewPager的,這樣可以更加方便的生成每個Page以及管理 每個Page的生命週期!當然它給我們提供了兩個不同的Adapter,他們分別是: FragmentPageAdapter和FragmentStatePagerAdapter! 而我們本節用到的則是前者:FragmentPageAdapter! 另外要說一點的是ViewPager的快取機制: ViewPager會快取當前頁,前一頁,以及後一頁,比如有1,2,3,4這四個頁面: 當我們處於第一頁:快取1,2
——> 處於第二頁:快取 1,2,3
——> 處於第三頁:快取2,3,4 ——> 處於第四頁快取3,4這樣!
2)使用PagerAdapter要重寫相關方法:
getCount( ):獲得viewpager中有多少個view
destroyItem( ):移除一個給定位置的頁面。介面卡有責任從容器中刪除這個檢視。這是為了確保 在finishUpdate(viewGroup)返回時檢視能夠被移除。
instantiateItem( ):①將給定位置的view新增到ViewGroup(容器)中,建立並顯示出來 ②返回一個代表新增頁面的Object(key),通常都是直接返回view本身就可以了, 當然你也可以自定義自己的key,但是key和每個view要一一對應的關係
isViewFromObject( ):判斷instantiateItem(ViewGroup, int)函式所返回來的Key與一個頁面檢視是否是 代表的同一個檢視(即它倆是否是對應的,對應的表示同一個View),通常我們直接寫 return view == object;就可以了,至於為什麼要這樣講起來比較複雜,後面有機會進行了解吧 貌似是ViewPager中有個儲存view狀態資訊的ArrayList,根據View取出對應資訊的吧!
PS:不一定要重寫所有方法~
2.實現效果圖以及工程目錄結構:
先來看下我們要實現的效果吧
3.程式碼實現:
Step 1:相關資原始檔的準備:
Step 2:編寫activity_main.xml的佈局檔案:
activity_mian.xml:
<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"
tools:context=".MainActivity">
<RelativeLayout
android:id="@+id/ly_top_bar"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="@color/bg_topbar">
<TextView
android:id="@+id/txt_topbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:text="提醒"
android:textColor="@color/text_topbar"
android:textSize="18sp" />
<View
android:layout_width="match_parent"
android:layout_height="2px"
android:layout_alignParentBottom="true"
android:background="@color/div_white" />
</RelativeLayout>
<RadioGroup
android:id="@+id/rg_tab_bar"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_alignParentBottom="true"
android:background="@color/bg_white"
android:orientation="horizontal">
<RadioButton
android:id="@+id/rb_channel"
style="@style/tab_menu_item"
android:drawableTop="@drawable/tab_menu_channel"
android:text="@string/tab_menu_alert" />
<RadioButton
android:id="@+id/rb_message"
style="@style/tab_menu_item"
android:drawableTop="@drawable/tab_menu_message"
android:text="@string/tab_menu_profile" />
<RadioButton
android:id="@+id/rb_better"
style="@style/tab_menu_item"
android:drawableTop="@drawable/tab_menu_better"
android:text="@string/tab_menu_pay" />
<RadioButton
android:id="@+id/rb_setting"
style="@style/tab_menu_item"
android:drawableTop="@drawable/tab_menu_setting"
android:text="@string/tab_menu_setting" />
</RadioGroup>
<View
android:id="@+id/div_tab_bar"
android:layout_width="match_parent"
android:layout_height="2px"
android:layout_above="@id/rg_tab_bar"
android:background="@color/div_white" />
<androidx.viewpager.widget.ViewPager
android:id="@+id/vpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/div_tab_bar"
android:layout_below="@id/ly_top_bar" />
</RelativeLayout>
Step 3:編寫Fragment的佈局以及程式碼:
PS:這裡為了順便演示ViewPager的機制,特意寫成了四個Fragment!在onCreateView中列印建立Log!
fg_content.xml:fg_content2.xml:fg_content.xml3:fg_content4.xml:
新增的元件隨意,下面是fg_content.xml
<?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="match_parent"
android:background="@color/bg_white"
android:orientation="vertical">
<TextView
android:id="@+id/txt_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="呵呵"
android:textColor="@color/text_yellow"
android:textSize="20sp" />
</LinearLayout>
MyFragment1.java:
/**
* Created by Jay on 2015/8/28 0028.
*/
public class MyFragment1 extends Fragment {
public MyFragment1() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fg_content, container, false);
TextView txt_content = (TextView) view.findViewById(R.id.txt_content);
txt_content.setText("第一個Fragment");
Log.e("HEHE", "1日狗");
return view;
}
}
其他三個照葫蘆畫瓢,換點東西就好!
Step 4:自定義FragmentPagerAdapter類:
程式碼很簡單,只需傳遞一個FragmentManager過來,其他都在這裡完成!
public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
// private final int PAGER_COUNT = 4;
// private MyFragment1 myFragment1 = null;
// private MyFragment2 myFragment2 = null;
// private MyFragment3 myFragment3 = null;
// private MyFragment4 myFragment4 = null;
private List<Fragment> mList = new ArrayList<>();
public MyFragmentPagerAdapter(FragmentManager fm, List<Fragment> mList) {
super(fm);
// myFragment1 = new MyFragment1();
// myFragment2 = new MyFragment2();
// myFragment3 = new MyFragment3();
// myFragment4 = new MyFragment4();
this.mList = mList;
}
@Override
public int getCount() {
return mList.size();
}
@Override
public Object instantiateItem(ViewGroup vg, int position) {
return super.instantiateItem(vg, position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
System.out.println("position Destory" + position);
super.destroyItem(container, position, object);
}
@Override
public Fragment getItem(int position) {
return mList.get(position);
}
}
Step 5:MainActivity的編寫:
邏輯很簡單,自己看~
MainActivity.java:
public class MainActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener,
ViewPager.OnPageChangeListener {
//UI Objects
private TextView txt_topbar;
private RadioGroup rg_tab_bar;
private RadioButton rb_channel;
private RadioButton rb_message;
private RadioButton rb_better;
private RadioButton rb_setting;
private ViewPager vpager;
private MyFragmentPagerAdapter mAdapter;
//幾個代表頁面的常量
public static final int PAGE_ONE = 0;
public static final int PAGE_TWO = 1;
public static final int PAGE_THREE = 2;
public static final int PAGE_FOUR = 3;
private MyFragment1 myFragment1 = null;
private MyFragment2 myFragment2 = null;
private MyFragment3 myFragment3 = null;
private MyFragment4 myFragment4 = null;
private List<Fragment> mList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
mAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(), mList);
bindViews();
rb_channel.setChecked(true);
}
private void initData() {
myFragment1 = new MyFragment1();
myFragment2 = new MyFragment2();
myFragment3 = new MyFragment3();
myFragment4 = new MyFragment4();
mList.add(myFragment1);
mList.add(myFragment2);
mList.add(myFragment3);
mList.add(myFragment4);
}
private void bindViews() {
txt_topbar = (TextView) findViewById(R.id.txt_topbar);
rg_tab_bar = (RadioGroup) findViewById(R.id.rg_tab_bar);
rb_channel = (RadioButton) findViewById(R.id.rb_channel);
rb_message = (RadioButton) findViewById(R.id.rb_message);
rb_better = (RadioButton) findViewById(R.id.rb_better);
rb_setting = (RadioButton) findViewById(R.id.rb_setting);
rg_tab_bar.setOnCheckedChangeListener(this);
vpager = (ViewPager) findViewById(R.id.vpager);
vpager.setAdapter(mAdapter);
vpager.setCurrentItem(0);
vpager.addOnPageChangeListener(this);
}
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.rb_channel:
vpager.setCurrentItem(PAGE_ONE);
break;
case R.id.rb_message:
vpager.setCurrentItem(PAGE_TWO);
break;
case R.id.rb_better:
vpager.setCurrentItem(PAGE_THREE);
break;
case R.id.rb_setting:
vpager.setCurrentItem(PAGE_FOUR);
break;
}
}
//重寫ViewPager頁面切換的處理方法
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
//state的狀態有三個,0表示什麼都沒做,1正在滑動,2滑動完畢
if (state == 2) {
switch (vpager.getCurrentItem()) {
case PAGE_ONE:
rb_channel.setChecked(true);
break;
case PAGE_TWO:
rb_message.setChecked(true);
break;
case PAGE_THREE:
rb_better.setChecked(true);
break;
case PAGE_FOUR:
rb_setting.setChecked(true);
break;
}
}
}
}
PS:另外獲取FragmentManager的方法不是直接用getFragmentManager()而是使用 getSupportFragmentManager()哦!
注意:如果 ViewPager 放在 RadioButton 後,RadioButton 的點選事件會失效。
新聞(購物)類App列表Fragment的簡單實現
相信大家對點選列表,然後進入詳情這種App並不陌生吧,在購物類App和新聞類App中最為常見: 下面我們簡單來講一下流程邏輯!
嘿嘿,市面上很多APP都是這種樣子的,而這個可以用我們學到的Fragment來實現: 可能gif動畫看不清,筆者用介面原型工具畫個大概吧:
大概就這樣,中間區域是一個佈局容器,一般是FrameLayout,然後我們將一個Fragment replace 到這個容器中或者add也行,而這個Fragment中有一個listview,當我們點選這個ListView中的一項, 中間容器中的Fragment就會被replace成對應詳細資訊的Fragment所替代,如果我們只是replace的話, 就不會儲存第一個Fragment的狀態,使用者又得從頭開始瀏覽,這肯定是很不方便的,這裡我們可以 通過Fragment棧的addtobackStack和popbackstack來解決這個問題!當replace的同時,我們將被替換 的Fragment新增到stack中,當使用者點選回退按鈕時,呼叫popbackstack彈出棧,具體實現見下述程式碼 示例!
2.程式碼示例:簡單新聞類APP列表和內容切換的實現
執行效果圖:
實現程式碼:
Step 1:先把兩個Fragment以及Activity的佈局實現了
fg_newlist.xml:
<?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="match_parent"
android:background="@color/white"
android:orientation="horizontal">
<ListView
android:id="@+id/list_news"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
fg_context.xml:
<?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="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/txt_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="@color/blue"
android:textSize="20sp" />
</LinearLayout>
activity_main.xml:
<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"
tools:context=".MainActivity">
<TextView
android:id="@+id/txt_title"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="@color/blue"
android:textColor="@color/white"
android:text="新聞列表"
android:textSize="20sp"
android:textStyle="bold"
android:gravity="center"/>
<FrameLayout
android:id="@+id/fl_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/txt_title"/>
</RelativeLayout>
Step 2:實現我們的業務Bean類和自定義BaseAdapter類:
Data.java:
/**
* Created by Jay on 2015/9/6 0006.
*/
public class Data {
private String new_title;
private String new_content;
public Data(){}
public Data(String new_title, String new_content) {
this.new_title = new_title;
this.new_content = new_content;
}
public String getNew_title() {
return new_title;
}
public String getNew_content() {
return new_content;
}
public void setNew_title(String new_title) {
this.new_title = new_title;
}
public void setNew_content(String new_content) {
this.new_content = new_content;
}
}
MyAdapter.java:
public class MyAdapter extends BaseAdapter {
private List<Data> mData;
private Context mContext;
public MyAdapter(List<Data> mData, Context mContext) {
this.mData = mData;
this.mContext = mContext;
}
@Override
public int getCount() {
return mData.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if(convertView == null){
convertView = LayoutInflater.from(mContext).inflate(R.layout.activity_main,parent,false);
viewHolder = new ViewHolder();
viewHolder.txt_title = (TextView) convertView.findViewById(R.id.txt_title);
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.txt_title.setText(mData.get(position).getNew_title());
return convertView;
}
private class ViewHolder{
TextView txt_title;
}
}
Step 3:MainActivity的實現
MainActivity.java:
public class MainActivity extends AppCompatActivity {
private TextView txt_title;
private FrameLayout fl_content;
private Context mContext;
private ArrayList<Data> datas = null;
private FragmentManager fManager = null;
private long exitTime = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = MainActivity.this;
fManager = getFragmentManager();
bindViews();
datas = new ArrayList<Data>();
for (int i = 1; i <= 20; i++) {
Data data = new Data("新聞標題" + i, i + "~新聞內容~~~~~~~~");
datas.add(data);
}
NewListFragment nlFragment = new NewListFragment(fManager, datas);
FragmentTransaction ft = fManager.beginTransaction();
ft.replace(R.id.fl_content, nlFragment);
ft.commit();
}
private void bindViews() {
txt_title = (TextView) findViewById(R.id.txt_title);
fl_content = (FrameLayout) findViewById(R.id.fl_content);
}
//點選回退鍵的處理:判斷Fragment棧中是否有Fragment
//沒,雙擊退出程式,否則像是Toast提示
//有,popbackstack彈出棧
@Override
public void onBackPressed() {
if (fManager.getBackStackEntryCount() == 0) {
if ((System.currentTimeMillis() - exitTime) > 2000) {
Toast.makeText(getApplicationContext(), "再按一次退出程式",
Toast.LENGTH_SHORT).show();
exitTime = System.currentTimeMillis();
} else {
super.onBackPressed();
}
} else {
fManager.popBackStack();
txt_title.setText("新聞列表");
}
}
}
Step 4:列表Fragment的實現:
NewListFragment.java:
package com.jay.fragmentdemo4;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
/**
* Created by Jay on 2015/9/6 0006.
*/
public class NewListFragment extends Fragment implements AdapterView.OnItemClickListener {
private FragmentManager fManager;
private ArrayList<Data> datas;
private ListView list_news;
public NewListFragment(FragmentManager fManager, ArrayList<Data> datas) {
this.fManager = fManager;
this.datas = datas;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fg_newlist, container, false);
list_news = (ListView) view.findViewById(R.id.list_news);
MyAdapter myAdapter = new MyAdapter(datas, getActivity());
list_news.setAdapter(myAdapter);
list_news.setOnItemClickListener(this);
return view;
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
FragmentTransaction fTransaction = fManager.beginTransaction();
NewContentFragment ncFragment = new NewContentFragment();
Bundle bd = new Bundle();
bd.putString("content", datas.get(position).getNew_content());
ncFragment.setArguments(bd);
//獲取Activity的控制元件
TextView txt_title = (TextView) getActivity().findViewById(R.id.txt_title);
txt_title.setText(datas.get(position).getNew_content());
//加上Fragment替換動畫
fTransaction.setCustomAnimations(R.anim.fragment_slide_left_enter, R.anim.fragment_slide_left_exit);
fTransaction.replace(R.id.fl_content, ncFragment);
//呼叫addToBackStack將Fragment新增到棧中
fTransaction.addToBackStack(null);
fTransaction.commit();
}
}
Step 5:內容Fragment的實現:
NewContentFragment.java:
/**
* Created by Jay on 2015/9/6 0006.
*/
public class NewContentFragment extends Fragment {
NewContentFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fg_content, container, false);
TextView txt_content = (TextView) view.findViewById(R.id.txt_content);
//getArgument獲取傳遞過來的Bundle物件
txt_content.setText(getArguments().getString("content"));
return view;
}
}
相關文章
- Java學習筆記——第二十二天Java筆記
- android基礎學習-android篇day17-Android Fragment(碎片)基本使用AndroidFragment
- Android開發學習之路Android
- Android開發學習之路03Android
- Android 開發學習筆記Android筆記
- Android開發學習(9)--BeatBox(2)Android
- Android之FragmentAndroidFragment
- Android開發教程 - 使用Data Binding(四)在Fragment中的使用AndroidFragment
- Android 開發學習程式0.32 dwonloadmanager使用Android
- Android基礎—FragmentAndroidFragment
- 第四十二天學習javaJava
- 【經驗】學習android開發的步驟Android
- Android 開發者學習路線(2020 版)Android
- Android輸入法開發 新手學習指引Android
- Android--單Activity+多Fragment,玩轉FragmentAndroidFragment
- 教育學習類app是怎麼開發的APP
- Android 碎片(Fragment)講解AndroidFragment
- 現在學習Android開發還有前景嗎Android
- Android開發學習之路--React-Native混合開發初體驗AndroidReact
- Android | Activity和Fragment最全生命週期+發現大牛AndroidFragment
- 使用Kotlin高效地開發Android App(二)KotlinAndroidAPP
- 使用Kotlin高效地開發Android App(四)KotlinAndroidAPP
- 使用Kotlin高效地開發Android App(三)KotlinAndroidAPP
- 使用Kotlin高效地開發Android App(一)KotlinAndroidAPP
- 直播app開發,Android ListView好友列表展示APPAndroidView
- Android 點將臺:撒豆成兵[- Fragment -]AndroidFragment
- Android Jetpack - Fragment官方說明AndroidJetpackFragment
- 史上最全的Android開發學習教程集錦【初學者】Android
- 現在學習Android開發還有錢途嗎?Android
- Android開發者珍藏必備【學習資料篇】Android
- 開發了5年android,我開始了go學習之旅AndroidGo
- iOS初級開發學習筆記:APP生命週期的學習總結iOS筆記APP
- Android小技巧:Android開發究竟該如何學習,年薪超過80萬!Android
- 安卓學習筆記20:Fragment入門安卓筆記Fragment
- Android Flutter 混合開發高仿大廠AppAndroidFlutterAPP
- Android優化--Fragment懶載入Android優化Fragment
- Android面試題之Fragment篇Android面試題Fragment
- Android ViewPager2 + Fragment 聯動AndroidViewpagerFragment