《第一行程式碼Android》學習總結第四章 Fragment應用實踐
Fragment應用實踐-----簡易新聞應用佈局(可同時相容手機與平板)
1、在app/build.gradle新增依賴庫
compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
2、新建News新聞實體類
public class News { private String title; //新聞標題 private String content; //新聞內容 public String getContent() { return content; } public String getTitle() { return title; } public void setContent(String content) { this.content = content; } public void setTitle(String title) { this.title = title; } }
3、新建news_content_frag.xml佈局。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/visibility_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:visibility="invisible"> <TextView android:id="@+id/news_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:padding="10dp" android:textSize="20sp"/> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="#000"/> <TextView android:id="@+id/news_content" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:padding="15dp" android:textSize="18sp"/> </LinearLayout> <View android:layout_width="1dp" android:layout_height="match_parent" android:layout_alignParentLeft="true" android:background="#000"/> </RelativeLayout>
新聞內容佈局共分為兩個部分,頭部顯示新聞標題,正文顯示新聞內容,中間用一條細線分隔開。其中細線用高或寬為1dp的View實現。
4、新建NewContentFragment類,繼承自Fragment。
public class NewContentFragment extends Fragment { private View view; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { //載入佈局 view = inflater.inflate(R.layout.news_content_flag, container, false); return view; } // refresh()方法用於將新聞標題與內容顯示在介面上。 public void refresh(String newsTitle, String newsContent){ View visibilityLayout = view.findViewById(R.id.visibility_layout); visibilityLayout.setVisibility(View.VISIBLE); TextView newTitleText = view.findViewById(R.id.news_title); TextView newContentText = view.findViewById(R.id.news_content); newTitleText.setText(newsTitle); newContentText.setText(newsContent); } }
5、新建一個活動NewsContentActivity,並將佈局設定為news_content.xml。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
//程式碼的複用性,直接在不居中引用NewContentFragment,相當於直接載入了news_content_flag佈局。
<fragment
android:id="@+id/news_content_fragment"
android:name="com.launcher.fragmentbestpractice.NewContentFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
public class NewsContentActivity extends AppCompatActivity {
//更簡潔,更整齊的開啟另一Activity的編碼方式
public static void actionStart(Context context, String newsTitle, String newsContent){
Intent intent = new Intent(context,NewsContentActivity.class);
intent.putExtra("news_title",newsTitle);
intent.putExtra("news_content",newsContent);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_content);
//通過Intent傳入新聞標題與新聞內容
String newsTitle = getIntent().getStringExtra("news_title");
String newsContent = getIntent().getStringExtra("news_content");
//從佈局檔案中獲取Fragment例項
NewContentFragment newContentFragment = (NewContentFragment)
getSupportFragmentManager().findFragmentById(R.id.news_content_fragment);
//呼叫refresh()方法將新聞標題與內容顯示在介面上。
newContentFragment.refresh(newsTitle,newsContent);
}
}
6、建立用於顯示新聞列表的佈局,新建news_title_flag.xml,載入RecyclerView佈局。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/news_title_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
7、新建news_item.xml,作為RecyclerView的子項佈局其中包含一個TextView。
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/news_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:textSize="18sp"
android:paddingBottom="10dp"
android:paddingEnd="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp">
</TextView>
android:padding:表示給控制元件周圍加上補白,以免文字內容緊靠邊緣。
android:ellipsize:設定文字超出控制元件寬度時,文字的縮略方式。
8、新建NewsTitleFragment作為展示新聞列表的碎片。
public class NewsTitleFragment extends Fragment {
private boolean isTwoPage;
//載入news_title_flag佈局
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.news_title_flag, container, false);
return view;
}
//通過判斷能否找到id為news_content_layout的View來判斷當前是雙頁模式還是單頁模式。
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if(getActivity().findViewById(R.id.news_content_layout)!=null){
isTwoPage = true;
}else {
isTwoPage = false;
}
}
}
9、修改activity_main.xml程式碼,單頁模式。
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/news_title_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/news_title_fragment"
android:name="com.launcher.fragmentbestpractice.NewsTitleFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
10、新建layout-sw600dp資料夾,再新建一個activity_main.xml佈局,雙頁模式。
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/news_title_fragment"
android:name="com.launcher.fragmentbestpractice.NewsTitleFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<FrameLayout
android:id="@+id/news_content_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<fragment
android:id="@+id/news_content_fragment"
android:name="com.launcher.fragmentbestpractice.NewContentFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
</LinearLayout>
11、在NewsTitleFragment中新建NewsAdapter內部類作為RecyclerView的介面卡,將新聞列表通過RecyclerView展示出來。
內部類便於直接訪問NewsTitleFragment類的例項。
class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.ViewHolder>{
private List<News> mNewsList;
class ViewHolder extends RecyclerView.ViewHolder{
TextView newsTitleText;
public ViewHolder(View view) {
super(view);
newsTitleText = view.findViewById(R.id.news_title);
}
}
public NewsAdapter(List<News> mNewsList) {
this.mNewsList = mNewsList;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.news_item,parent,false);
final ViewHolder holder = new ViewHolder(view);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//點選項的News例項
News news = mNewsList.get(holder.getAdapterPosition());
//通過isTwoPage判斷為單頁還是雙頁模式
if(isTwoPage){
NewContentFragment newContentFragment = (NewContentFragment) getFragmentManager().findFragmentById(R.id.news_content_fragment);
newContentFragment.refresh(news.getTitle(),news.getContent());
}else{
NewsContentActivity.actionStart(getContext(),news.getTitle(),news.getContent());
}
}
});
return holder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
News news = mNewsList.get(position);
holder.newsTitleText.setText(news.getTitle());
}
@Override
public int getItemCount() {
return mNewsList.size();
}
}
12、改寫NewsTiltleFragment中的onCreateView()方法,使用RecyclerView,並向RecyclerView填充資料。
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.news_title_flag, container, false);
RecyclerView newTitleRecyclerView = view.findViewById(R.id.news_title_recycler_view);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
newTitleRecyclerView.setLayoutManager(linearLayoutManager);
NewsAdapter adapter = new NewsAdapter(getNews());
newTitleRecyclerView.setAdapter(adapter);
return view;
}
private List<News> getNews() {
List<News> newsList = new ArrayList<>();
for(int i=1; i<=50; i++){
News news =new News();
news.setTitle("This is a new Title"+i);
news.setContent("This is a new Content"+i);
newsList.add(news);
}
return newsList;
}