上次咱們用RecyclerView作了一個簡單的顯示筆記的小程序,今天咱們用ViewPager來擴展它的功能:當咱們點擊筆記列表的其中某條筆記時,它能夠跳到另一個頁面完整的顯示這條筆記的內容,更人性化的設計是,在某條筆記的詳情頁面,咱們能夠左右滑動以查看上一條或者下一條,而不是返回主列表再去選擇,話很少說,操做起來!java
1.首先咱們建立一個Activity,命名爲NotePagerActivity
2.定義NotePagerActivity的私有字段:android
public class NotePagerActivity extends AppCompatActivity { private static final String EXTRA_NOTE_ID = "com.aristark.note.note.id"; private ViewPager noteViewPager; private ArrayList<Note> notes; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_note_pager); } }
由於咱們是從列表Activity那裏點擊某一個筆記項才進入到NotePagerActivity,所以須要傳入該筆記項的UUID(很容易想到兩個Activity之間傳遞數據所使用的方法是Intent附加參數,也就是putExtra()方法,所以咱們將該常量命名爲EXTRA_NOTE_ID,養成這樣良好的命名方法對之後讀懂這段代碼是很重要的!先不用好奇爲何要把它設爲私有,一下子就明白其中的妙處了),noteViewPager和notes天然不用多說,這是今天的主角。小程序
3.在佈局中activity_note_pager設置ViewPager
直接上代碼app
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/activity_note_pager_view_pager"/>
4爲NotePagerActivity編寫newIntent方法ide
public static Intent newIntent(Context context,UUID uuid){ Intent i = new Intent(context,NotePagerActivity.class); i.putExtra(EXTRA_NOTE_ID,uuid); return i; }
這樣咱們每次想要啓動NotePagerActivity時只需調用這個靜態方法,而不用再balabalabala重複一堆昨天的故事。佈局
其實我也不知道爲何用設置這個詞,應該用使用?裝配?其實不須要太在乎,咱們的目的如今很簡單,就是按照ViewPager給的接口傳入相應的參數,讓它工做起來就行(對新手而言)!
先貼上NoteListsFragment的代碼測試
package com.aristark.note;
import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import java.util.ArrayList; import java.util.Calendar; import java.util.List; public class NotesListFragment extends Fragment { private RecyclerView noteRecycler; private NoteAdapter noteAdapter;
public NotesListFragment() { // Required empty public constructor }
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment // return inflater.inflate(R.layout.fragment_notes_list, container, false); View root = inflater.inflate(R.layout.fragment_notes_list,container,false); noteRecycler = (RecyclerView) root.findViewById(R.id.note_recycler_view); noteRecycler.setLayoutManager(new LinearLayoutManager(getActivity())); // NoteLab noteLab = NoteLab.getNoteLab(getActivity()); // ArrayList<Note> notes = noteLab.getNotes(); // noteAdapter = new NoteAdapter(notes); // noteRecycler.setAdapter(noteAdapter); updateView(); return root; } @Override public void onResume() { super.onResume(); updateView(); } private class NoteHolder extends RecyclerView.ViewHolder{ private TextView noteTitle; private TextView noteContent; private TextView noteDate; public NoteHolder(View root) { super(root); noteTitle = (TextView) root.findViewById(R.id.list_item_note_title); noteContent = (TextView) root.findViewById(R.id.list_item_note_content); noteDate = (TextView) root.findViewById(R.id.list_item_note_date); } public void bindView(Note n){ this.note = n; noteTitle.setText(note.getTitle()); noteContent.setText(note.getContent()); Calendar calendar = Calendar.getInstance(); calendar.setTime(note.getDate()); int year = calendar.get(1); int day = calendar.get(5); int month = calendar.get(2)+1; String date = year+"年"+month+"月"+day+"日"; noteDate.setText(date); } } private class NoteAdapter extends RecyclerView.Adapter<NoteHolder>{ private List<Note> notes; public NoteAdapter(List<Note> notes){ this.notes = notes; } public void setNotes(List<Note> notes) { this.notes = notes; } @Override public NoteHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater layoutInflater = LayoutInflater.from(getActivity()); View view = layoutInflater.inflate(R.layout.list_item_note,parent,false); return new NoteHolder(view); } @Override public void onBindViewHolder(NoteHolder holder, int position) { Note note = notes.get(position); holder.bindView(note); } @Override public int getItemCount() { return notes.size(); } } public void updateView(){ NoteLab noteLab = NoteLab.getNoteLab(getActivity()); ArrayList<Note> notes = noteLab.getNotes(); if (noteAdapter == null){ noteAdapter = new NoteAdapter(notes); noteRecycler.setAdapter(noteAdapter); return; } noteAdapter.setNotes(notes); noteRecycler.setAdapter(noteAdapter); } }
和上回的代碼略有不一樣,我作了一些小小的封裝。咱們把注意力集中到類NoteHolder的構造方法這裏來,它傳入的參數root的類型是View,也就是筆記列表項的每個筆記記錄,咱們在這裏設置一個監聽器,當用戶點擊的時候,咱們就讓頁面跳轉到筆記詳情頁面,也就是CrimePagerActivity,來,寫代碼:ui
public NoteHolder(View root) { super(root); root.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent i = NotePagerActivity.newIntent(getActivity(),note.getUuid());
startActivity(i); } }); noteTitle = (TextView) root.findViewById(R.id.list_item_note_title); noteContent = (TextView) root.findViewById(R.id.list_item_note_content); noteDate = (TextView) root.findViewById(R.id.list_item_note_date); }
下面把注意力轉移到CrimePagerActivity:
1.獲取ViewPager:this
noteViewPager = (ViewPager) findViewById(R.id.note_view_pager);
2.從傳來的Intent裏獲取uuid,並以此uuid從全局靜態對象NoteLab中獲取notes:設計
UUID uuid = (UUID)getIntent().getSerializableExtra(EXTRA_NOTE_ID); notes = NoteLab.getNoteLab(this).getNotes();
這裏再一次體會到了EXTRA_NOTE_ID的方便之處吧。
3.爲ViewPager設置Adapter(ViewPager和RecyclerView同樣,每一個頁面的佈局都是同樣的,只是填充的數據不同,由於須要Adapter去適配,這裏感嘆一句想到這種機制的大神真的應該膜拜!簡直解放了生產力有沒有!)OK,show you the code:
FragmentManager fragmentManager = getSupportFragmentManager(); noteViewPager.setAdapter(new FragmentPagerAdapter(fragmentManager) { @Override public Fragment getItem(int position) { return null; } @Override public int getCount() { return notes.size(); } });
是否是似曾相識?之因此要用FragmentPagerAdapter,是由於它能夠爲咱們省去從Activity中啓動Fragment的一系列事務代碼,十分方便。寫到這裏我突然忘記咱們把筆記詳情頁給忘了,沒有它咱們該拿什麼去顯示筆記的詳情呢,好吧,趕快去新建一個fragment命名爲NoteDetailFragment:
public class NoteDetailFragment extends Fragment { private static String ARG_NOTE_ID; private Note note; TextView noteDate; TextView noteTitle; TextView noteContent; public NoteDetailFragment() { // Required empty public constructor } public static Fragment newFragment(UUID uuid){ Bundle args = new Bundle(); args.putSerializable(ARG_NOTE_ID,uuid); Fragment fragment = new NoteDetailFragment(); fragment.setArguments(args); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); UUID uuid = (UUID) getArguments().getSerializable(ARG_NOTE_ID); note = NoteLab.getNoteLab(getActivity()).getNote(uuid); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment_note_detail,container,false); noteDate = (TextView) root.findViewById(R.id.note_date); noteTitle = (TextView) root.findViewById(R.id.note_title); noteContent = (TextView) root.findViewById(R.id.note_content); noteDate.setText(note.getDate().toString()); noteTitle.setText(note.getTitle()); noteContent.setText(note.getContent()); } return root; }
上面的newFragment方法和以前的newIntent所使用的技巧是同樣的。從Activity中啓動Fragment傳參的方法是setArguments,天然的,咱們就有了ARG_NOTE_ID這個常量。
對應的佈局文件代碼以下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="10dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/note_date" android:layout_weight="3"/> <View android:layout_height="1px" android:background="@android:color/darker_gray" android:layout_width="fill_parent"></View>
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/note_title"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/note_content" /> </LinearLayout> </LinearLayout> </LinearLayout>
回到NotePagerActivity中:
@Override public Fragment getItem(int position) { Note note = notes.get(position); return NoteDetailFragment.newFragment(note.getUuid()); }
好,編譯,運行,添加幾組測試數據後咱們會發現無論從哪條筆記記錄點擊進去,都是從第一條開始顯示,不用急,此時咱們能夠在getItem下面添加以下代碼:
for (int i=0;i<notes.size();i++){ if (notes.get(i).getUuid().equals(uuid)){ noteViewPager.setCurrentItem(i); break; } }
用setCurrentItem來設置正確的筆記項就好了。由於結果須要動態演示,我就不貼圖啦,若是有人須要代碼的話我就聯繫我吧!個人qq:891871898求批評指正!