创建列表明细应用1-使用fragment
Posted 大赵传奇
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了创建列表明细应用1-使用fragment相关的知识,希望对你有一定的参考价值。
笔记自《android编程权威指南第二版》
第七章,创建一个列表明细应用
fragment是一种控制器对象,activity可委派它完成一些任务,这些任务通常就是管理用户界面。(管理用户界面的fragment又称UI fragment。它自己也产生布局文件)
利用fragment,可轻松实现选择不同的列表项就显示对应的明细视图Activity负责以一个明细fragment替换另一个明细fragment
托管可以这样理解,activity在其视图层级里提供一处位置来放置fragment的视图。fragment本身不具有在屏幕上显示视图的能力。
添加支持库:
dependencies {
compile fileTree(include: [\'*.jar\'], dir: \'libs\')
androidTestCompile(\'com.android.support.test.espresso:espresso-core:2.2.2\', {
exclude group: \'com.android.support\', module: \'support-annotations\'
})
compile \'com.android.support:appcompat-v7:26.+\'
compile \'com.android.support.constraint:constraint-layout:1.0.0-alpha8\'
testCompile \'junit:junit:4.12\'
compile \'com.android.support:support-v4:26.0.0-alpha1\'
compile \'com.android.support:recyclerview-v7:26.0.0-alpha1\'
}
项目结构:
Crime实体类:
package com.homelink.testcriminal; import java.util.Date; import java.util.UUID; /** * Created by ysc on 2017/9/30. */ public class Crime { private UUID mId; private String mTitle; private Date mDate; private boolean mSolved; public Crime() { mId = UUID.randomUUID(); mDate = new Date(); } public UUID getId() { return mId; } public String getTitle() { return mTitle; } public void setTitle(String title) { mTitle = title; } public Date getDate() { return mDate; } public void setDate(Date date) { mDate = date; } public boolean isSolved() { return mSolved; } public void setSolved(boolean solved) { mSolved = solved; } }
SingleFragmentActivity抽象基类,用于CrimeActivity , CrimeListActivity。而这两个Activity又分别创建各自的Fragment
package com.homelink.testcriminal; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; /** * Created by ysc on 2017/9/30. */ public abstract class SingleFragmentActivity extends FragmentActivity { protected abstract Fragment createFragment(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_fragment); FragmentManager fm = getSupportFragmentManager(); Fragment fragment = fm.findFragmentById(R.id.fragment_container); if (fragment == null) { fragment = createFragment(); fm.beginTransaction() .add(R.id.fragment_container, fragment) .commit(); } } }
CrimeActitiy.java
package com.homelink.testcriminal; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.os.Bundle; public class CrimeActivity extends SingleFragmentActivity { @Override protected Fragment createFragment() { return new CrimeFragment(); } }
CrimeListActivity.java
package com.homelink.testcriminal; import android.support.v4.app.Fragment; /** * Created by ysc on 2017/9/30. */ public class CrimeListActivity extends SingleFragmentActivity { @Override protected Fragment createFragment() { return new CrimeListFragment(); } }
activity_fragment.xml 的layout,用于托管fragment。很简单,就只放了一个FrameLayout,用于承载Fragment
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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="com.homelink.testcriminal.CrimeActivity"> <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" /> </LinearLayout>
fragment_crime.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="wrap_content" android:orientation="vertical" > <TextView android: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" /> <TextView android: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" /> </LinearLayout>
横向:
<?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"> <TextView android: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" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/crime_details_label" style="?android:listSeparatorTextViewStyle" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="16dp" android:layout_marginRight="16dp" > <Button android:id="@+id/crime_date" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" /> <CheckBox android:id="@+id/crime_solved" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/crime_solved_label" /> </LinearLayout> </LinearLayout>
CrimeFragment.java控制器,展示数据
package com.homelink.testcriminal; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.text.Editable; import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; /** * Created by ysc on 2017/9/30. */ public class CrimeFragment extends Fragment { private Crime mCrime; private EditText mTitleField; private Button mDateButton; private CheckBox mSolvedCheckBox; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); mCrime = new Crime(); } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable 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 } @Override public void onTextChanged( CharSequence s, int start, int before, int count) { mCrime.setTitle(s.toString()); } @Override public void afterTextChanged(Editable s) { // This one too } }); mDateButton = (Button)v.findViewById(R.id.crime_date); mDateButton.setText(mCrime.getDate().toString()); mDateButton.setEnabled(false); return v; } }
列表项的控制CrimeListFragment.java:
package com.homelink.testcriminal; 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.CheckBox; import android.widget.TextView; import android.widget.Toast; import java.util.List; /** * Created by ysc on 2017/9/30. */ public class CrimeListFragment extends Fragment { private RecyclerView mCrimeRecyclerView; @Override public 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())); updateUI(); return view; } private CrimeAdapter mAdapter; private void updateUI() { CrimeLab crimeLab = CrimeLab.get(getActivity()); List<Crime> crimes = crimeLab.getCrimes(); mAdapter = new CrimeAdapter(crimes); mCrimeRecyclerView.setAdapter(mAdapter); } private class CrimeHolder extends RecyclerView.ViewHolder implements View.OnClickListener { private Crime mCrime; private TextView mTitleTextView; private TextView mDateTextView; private CheckBox mSolvedCheckBox; public CrimeHolder(View itemView) { super(itemView); itemView.setOnClickListener(this); mTitleTextView = (TextView) itemView.findViewById(R.id.list_item_crime_title_text_view); mDateTextView = (TextView) itemView.findViewById(R.id.list_item_crime_date_text_view); mSolvedCheckBox = (CheckBox)itemView.findViewById(R.id.list_item_crime_solved_check_box); } public void BindCrime(Crime crime){ mCrime = crime; mTitleTextView.setText(mCrime.getTitle()); mDateTextView.setText(mCrime.getDate().toString()); mSolvedCheckBox.setChecked(mCrime.isSolved()); } @Override public void onClick(View view) { Toast.makeText(getActivity(), mCrime.getTitle() + " clicked!", Toast.LENGTH_SHORT).show(); } } private class CrimeAdapter extends RecyclerView.Adapter<CrimeHolder> { private List<Crime> mCrimes; public CrimeAdapter(List<Crime> crimes) { mCrimes = crimes; } @Override public CrimeHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater layoutInflater = LayoutInflater.from(getActivity()); View view = layoutInflater.inflate(R.layout.list_item_crime, parent, false); return new CrimeHolder(view); } @Override public void onBindViewHolder(CrimeHolder holder, int position) { Crime crime = mCrimes.get(position); //holder.mTitleTextView.setText(crime.getTitle()); holder.BindCrime(crime); } @Override public int getItemCount() { return mCrimes.size(); } } }
数据从哪里来,单例的CrimeLab.java
package com.homelink.testcriminal; import android.content.Context; import java.util.ArrayList; import java.util.List; import java.util.UUID; /** * Created by ysc on 2017/9/30. */ public class CrimeLab { private static CrimeLab sCrimeLab; public static CrimeLab get(Context context) { if (sCrimeLab == null) { sCrimeLab = new CrimeLab(context); } return sCrimeLab; } private CrimeLab(Context context) { initCrimes(); } private List<Crime> mCrimes; private void initCrimes(){ mCrimes = new ArrayList<>(); for (int i = 0; i < 100; i++) { Crime crime = new Crime(); crime.setTitle("Crime #" + i); crime.setSolved(i % 2 == 0); // Every other one mCrimes.add(crime); } } public List<Crime> getCrimes() { return mCrimes; } public Crime getCrime(UUID id) { for (Crime crime : mCrimes) { if (crime.getId().equals(id)) { return crime; } } return null; } }
如果是显示列表呢,使用recyclerview,fragment_crime_list.xml布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/crime_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
其中列表项:list_item_crime.xml:
<?xml version="1.0" encoding="utf-8"?> <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="wrap_content"> <CheckBox android:id="@+id/list_item_crime_solved_check_box" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:padding="4dp"/> <TextView android:id="@+id/list_item_crime_title_text_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toLeftOf="@id/list_item_crime_solved_check_box" android:textStyle="bold" android:padding="4dp" tools:text="Crime Title"/> <TextView android:id="@+id/list_item_crime_date_text_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toLeftOf="@id/list_item_crime_solved_check_box" android:layout_below="@id/list_item_crime_title_text_view" android:padding="4dp" tools:text="Crime Date"/> </RelativeLayout>
当然先修改一下AndroidManifest.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.homelink.testcriminal">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".CrimeListActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".CrimeActivity">
</activity>
</application>
</manifest>
运行:
以上是关于创建列表明细应用1-使用fragment的主要内容,如果未能解决你的问题,请参考以下文章