Android開發3、4周——Criminallntent項目

來源:互聯網
上載者:User

標籤:字串資源   property   listener   undle   final   lint   ada   android   pac   

CriminalIntent項目開發1.fragment的引入

採用fragment而不是activity來管理應用UI,可繞開Android系統activity使用規則的限制。

fragment是一種控制器對象,activity可委派它完成一些任務。

這些任務通常就是系統管理使用者介面。受管的使用者介面可以是一整屏或是整屏的一部分。系統管理使用者介面的fragment又稱為UI fragment。

它自己也有產生於布局檔案的視圖。fragment視圖包含了使用者可以互動的可視化UI元素。

利用fragment,可輕鬆實現選擇不同的清單項目就顯示對應的明細視圖Activity負責以一個明細fragment替換另一個明細fragment,1.1所示。

這樣,視圖切換的過程中,就不用銷毀activity了。

                                                                                         圖1.1

2.fragment與支援庫

我們要用到兩個重要的支援庫類,一個是Fragment類( android.support.v4.app.Fragment )。

另一個是FragmentActivity類( android.support.v4.app.Fragment- Activity )。

使用fragment的前提是:activity知道如何管理fragment、FragmentActivity類知道如何管理支援版本的fragment。

3.定義[內容] 檢視建立fragment容器布局(activity_crime.xml)如下
<
FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/fragment_container"android:layout_width="match_parent"android:layout_height="match_parent"/>
4.定義CrimeFragment布局

CrimeFragment視圖將顯示包含在Crime類執行個體中的資訊。

該布局包括一個垂直LinearLayout布局(含有一個EditText組件)。

EditText組件有一塊地區,可供使用者添加或編輯文字資訊。

fragment視圖的布局檔案(fragment_crime.xml)如下
<
LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><
EditText android:id="@+id/crime_title"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="@string/crime_title_hint"/></LinearLayout>
5.建立CrimeFragment類繼承Fragment類(CrimeFragment.java)如下
public class CrimeFragment extends Fragment {}

修改代碼繼承Fragment類時 ,我們需要選擇Fragment(android.support.v4.app)包

6.實現fragment生命週期覆蓋Fragment.onCreate(Bundle)方法(CrimeFragment.java)如下
public class CrimeFragment extends Fragment {private Crime mCrime;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mCrime = new Crime();}}

Fragment.onCreate(Bundle)是公用方法,而Activity.onCreate(Bundle)是保護方法。

這是因為只有Fragment.onCreate(...)方法及其他Fragment生命週期方法是公用方法,託管fragment的activity才能調用它們。

7.覆蓋onCreateView(...)方法(CrimeFragment.java)如下
@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View v = inflater.inflate(R.layout.fragment_crime, container, false);return v;}

在onCreateView(...)方法中,fragment的視圖是直接通過調用LayoutInflater.inflate(...)方法並傳入布局的資源ID產生的。

第二個參數是視圖的父視圖,因為我們通常需要父視圖來正確配置組件。

第三個參數告知布局產生器是否將產生的視圖添加給父視圖(這裡,我們傳入了false參數,因為我們將以activity代碼的方式添加視圖。)

8.在fragment中關聯組件產生並使用EditText組件(CrimeFragment.java)如下
public class CrimeFragment extends Fragment {private Crime mCrime;private EditText mTitleField;
@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {  View v = inflater.inflate(R.layout.fragment_crime, container, false);  mTitleField = (EditText)v.findViewById(R.id.crime_title);  mTitleField.addTextChangedListener(new TextWatcher() {  @Override  public void beforeTextChanged(  CharSequence s, int start, int count, int after) {  // This space intentionally left blank}@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {mCrime.setTitle(s.toString());}@Overridepublic void afterTextChanged(Editable s) {// This one too}});return v;}}

Fragment.onCreateView(...)方法中的組件引用幾乎等同於Activity.onCreate(...)方法的處理。唯一的區別是我們調用了fragment視圖的View.findViewById(int)方法。

9.添加UI fragment到FragmentManager

FragmentManager 類具體管理的是:

? fragment隊列;

? fragment交易回復棧。

擷取FragmentManager(CrimeActivity.java)如下
FragmentManager fm = getSupportFragmentManager();
添加一個CrimeFragment(CrimeActivity.java)如下
Fragment fragment = fm.findFragmentById(R.id.fragment_container);if (fragment == null) {fragment = new CrimeFragment();fm.beginTransaction().add(R.id.fragment_container, fragment).commit();}

fragment事務被用來添加、移除、附加、分離或替換fragment隊列中的fragment。這是使用fragment在運行時組裝和重新組裝使用者介面的關鍵。

FragmentManager管理著fragment交易回復棧。

10.使用布局與組件建立使用者介面

開啟Crime.java檔案,新增兩個執行個體變數。

Date變數表示crime發生的時間,boolean變數表示crime是否已得到處理。

添加更多變數(Crime.java)如下
private Date mDate;private boolean mSolved;public Crime() {mId = UUID.randomUUID();mDate = new Date();}
添加新組件(fragment_crime.xml)如下

為CrimeFragment的布局添加四個組件:兩個TextView組件、一個Button組件以及一個CheckBox組件

<
TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="@string/crime_title_label"style="?android:listSeparatorTextViewStyle"/><
EditText android:id="@+id/crime_title"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="16dp"android:layout_marginRight="16dp"android:hint="@string/crime_title_hint"/><
TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="@string/crime_details_label"style="?android:listSeparatorTextViewStyle"/><
Button android:id="@+id/crime_date"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="16dp"android:layout_marginRight="16dp"/><CheckBox android:id="@+id/crime_solved"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="16dp"android:layout_marginRight="16dp"android:text="@string/crime_solved_label"/>
添加字串資源(strings.xml)如下
<string name="crime_title_label">Title</string><string name="crime_details_label">Details</string><string name="crime_solved_label">Solved</string>
添加組件執行個體變數(CrimeFragment.java)如下

接下來,要讓CheckBox顯示Crime是否已得到處理。使用者勾選清除CheckBox時,Crime的mSolved變數的狀態值也需得到相應的更新。

private Button mDateButton;private CheckBox mSolvedCheckBox;
設定Button上的文字顯示(CrimeFragment.java)如下
mDateButton = (Button)v.findViewById(R.id.crime_date);mDateButton.setText(mCrime.getDate().toString());mDateButton.setEnabled(false);

禁用按鈕可以確保它不響應使用者的單擊事件。禁用後,按鈕的外觀樣式也會發生改變(變為灰色),表明它已處于禁用狀態。

偵聽CheckBox狀態的變化(CrimeFragment.java)如下
mSolvedCheckBox = (CheckBox)v.findViewById(R.id.crime_solved);mSolvedCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {@Overridepublic void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {// Set the crime‘s solved propertymCrime.setSolved(isChecked);}});

建立OnCheckedChangeListener時需要匯入android.widget.CompoundButton的包。

11.使用RecyclerView

首先要匯入recyclerview-v7支援庫

在布局檔案中添加RecyclerView視圖(fragment_crime_list.xml)如下
<android.support.v7.widget.RecyclerViewxmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/crime_recycler_view"android:layout_width="match_parent"android:layout_height="match_parent"/>
為CrimeListFragment配置視圖(CrimeListFragment.java)如下
private RecyclerView mCrimeRecyclerView;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View view = inflater.inflate(R.layout.fragment_crime_list, container, false);mCrimeRecyclerView = (RecyclerView) view.findViewById(R.id.crime_recycler_view);mCrimeRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));return view;}

RecyclerView類的任務就是回收再利用以及定位螢幕上的TextView視圖。

實際上,定位的任務被委託給了LayoutManager。

除了在螢幕上定位清單項目,LayoutManager還負責定義螢幕滾動行為。

因此,沒有LayoutManager,RecyclerView也就無法正常工作了。

12.從fragment中啟動activity

在CrimeListFragment的CrimeHolder類裡,用啟動CrimeActivity執行個體的代碼,替換Toast訊息處理代碼。

啟動CrimeActivity(CrimeListFragment.java)如下
Intent intent = new Intent(getActivity(), CrimeActivity.class);startActivity(intent);
13.使用ViewPager

為UI添加ViewPager後,使用者可滑動螢幕,切換查看不同清單項目的明細頁面。

建立ViewPager(CrimePagerActivity.java)如下
public class CrimePagerActivity extends FragmentActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_crime_pager);}}

注意:必須使用ViewPager的包名全稱(android.support.v4.view.ViewPager)。13.1所示。

 

                                                       圖13.1

設定pager adapter(CrimePagerActivity.java)如下
public class CrimePagerActivity extends FragmentActivity {  private ViewPager mViewPager;  private List<Crime> mCrimes;@Overrideprotected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_crime_pager);  mViewPager = (ViewPager) findViewById(R.id.activity_crime_pager_view_pager);  mCrimes = CrimeLab.get(this).getCrimes();  FragmentManager fragmentManager = getSupportFragmentManager();  mViewPager.setAdapter(new FragmentStatePagerAdapter(fragmentManager) {  @Override  public Fragment getItem(int position) {  Crime crime = mCrimes.get(position);  return CrimeFragment.newInstance(crime.getId());  }@Override  public int getCount() {
return mCrimes.size();  }});}}

在activity視圖中找到ViewPager後,我們從CrimeLab中(crime的List)擷取資料集,然後擷取activity的FragmentManager執行個體。

設定adapter為FragmentStatePagerAdapter的一個匿名執行個體。建立Fragment-StatePagerAdapter執行個體需要FragmentManager。

建立newIntent方法(CrimePagerActivity.java)如下
private static final String EXTRA_CRIME_ID ="com.bignerdranch.android.criminalintent.crime_id";
public static Intent newIntent(Context packageContext, UUID crimeId) {Intent intent = new Intent(packageContext, CrimePagerActivity.class);intent.putExtra(EXTRA_CRIME_ID, crimeId);return intent;}
UUID crimeId = (UUID) getIntent().getSerializableExtra(EXTRA_CRIME_ID);

然後需要修改CrimeListFragment,使得使用者單擊某個清單項目時,CrimeListFragment啟動的是CrimePagerActivity執行個體。

配置啟動CrimePagerActivity(CrimeListFragment.java)
Intent intent = CrimePagerActivity.newIntent(getActivity(), mCrime.getId());

Android開發3、4周——Criminallntent項目

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.