参考文章:
第二个项目CriminalIntent应用开发阶段总结(一)(二)https://www.cnblogs.com/hj0407/
android编程权威指南第七章-CriminalIntent应用https://blog.csdn.net/weixin_43749381/article/details/107465847
Android Criminal实例--(1)创建fragment并添加至activityhttps://blog.csdn.net/ayangann915/article/details/81284856
一、项目创建
二、代码详情
1. values布局
(1)strings.xml
<resources>
<string name="app_name">学号+姓名</string>
<string name="hello_blank_fragment">Hello blank fragment</string>
</resources>
2. layout布局
(1)activity_crime_list.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
android:id="@+id/list_fragment_container"
tools:context=".CrimeListActivity">
</FrameLayout>
(2)fragment_crime.xml??
<?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="Title" />
<EditText
android:id="@+id/crime_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:text="crime_title" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Details" />
<Button
android:id="@+id/crime_date"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:text="Crime Date" />
<CheckBox
android:id="@+id/list_item_crime_solved"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:text="解决了" />
</LinearLayout>
(3)fragment_crime_list.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView 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=".CrimeListFragment"
android:id="@+id/crime_recycleview">
</androidx.recyclerview.widget.RecyclerView>
(4)list_item_crime.xml?
<?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="wrap_content"
android:id="@+id/list_item"
android:padding="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/list_item_crime_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="标题" />
<TextView
android:id="@+id/list_item_crime_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="日期" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical">
<CheckBox
android:id="@+id/list_item_crime_solved"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:text="解决了" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
3. Java布局
(1)CrimeListActivity
public class CrimeListActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_crime_list);
//获取FragmentManager
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.list_fragment_container);
if (fragment == null) {
fragment = new CrimeListFragment();
fm.beginTransaction()
.add(R.id.list_fragment_container, fragment)
.commit();
}
}
}
(2)Crime?
public class Crime implements Serializable {
private UUID mId;
private String mTitle;
private Date mDate;
private boolean mSolved;
public Crime() {
mId = UUID.randomUUID();
mDate = new Date();
}
public Crime(UUID mId, String mTitle, Date mDate, boolean mSolved) {
this.mId = mId;
this.mTitle = mTitle;
this.mDate = mDate;
this.mSolved = mSolved;
}
@Override
public String toString() {
return "Crime{" +
"mId=" + mId +
", mTitle='" + mTitle + '\'' +
", mDate=" + mDate +
", mSolved=" + mSolved +
'}';
}
public String getmTitle() {
return mTitle;
}
public void setmTitle(String mTitle) {
this.mTitle = mTitle;
}
public Date getmDate() {
return mDate;
}
public void setmDate(Date mDate) {
this.mDate = mDate;
}
public boolean ismSolved() {
return mSolved;
}
public void setmSolved(boolean mSolved) {
this.mSolved = mSolved;
}
public UUID getmId() {
return mId;
}
public void setmId(UUID mId) {
this.mId = mId;
}
}
(3)CrimeFragment
/**
* 一个简单的{@link Fragment}子类。
* 使用{@link CrimeFragment#newInstance}工厂方法
* 创建一个fragment的实例。
* 继承Fragment类
*/
public class CrimeFragment extends Fragment {
// TODO:重命名参数参数,选择匹配的名称
// 片段初始化参数,例如ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO:重命名和更改参数类型
private String mParam1;
private String mParam2;
private Crime crime;
private EditText crimeTitle;
private Button crimeDate;
private CheckBox crimeSolved;
public CrimeFragment() {
// 需要空的公共构造函数
}
/**
* 使用此工厂方法创建一个新的实例
* 这个片段使用提供的参数。
* *@param param1参数1。
* *@param param2参数2。
*
* @return一个新的片段CrimeFragment实例。
*/
// TODO:重命名和更改参数的类型和数量
public static CrimeFragment newInstance(Crime crime) {
CrimeFragment fragment = new CrimeFragment();
Bundle args = new Bundle();
args.putSerializable("crime", crime);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
this.crime = (Crime) getArguments().getSerializable("crime");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_crime, container, false);
//todo 注意理解此处的v是什么?和Activity中findViewById有什么相同和不同之处
crimeTitle = v.findViewById(R.id.crime_title);
crimeDate = v.findViewById(R.id.crime_date);
crimeSolved = v.findViewById(R.id.list_item_crime_solved);
crimeTitle.setText(crime.getmTitle());
crimeSolved.setChecked(crime.ismSolved());
//todo 增加事件响应代码
crimeTitle.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
crime.setmTitle(charSequence.toString());
}
@Override
public void afterTextChanged(Editable editable) {
}
});
crimeDate.setText(crime.getmDate().toString());
crimeDate.setEnabled(false);
crimeSolved.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
crime.setmSolved(isChecked);
}
});
return v;
}
}
(4)CrimeListFragment
/**
* 一个简单的{@link Fragment}子类。
* 使用{@link CrimeListFragment#newInstance}工厂方法
* 创建一个fragment的实例。
* 继承Fragment类
*/
public class CrimeListFragment extends Fragment {
// TODO:重命名参数参数,选择匹配的名称
// 片段初始化参数,例如ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO:重命名和更改参数类型
private String mParam1;
private String mParam2;
//为CrimeListFragment配置视图
private RecyclerView mRecyclerview;
private CrimeAdapter mCimeAdapter;
public CrimeListFragment() {
// 需要空的公共构造函数
}
/**
* 使用此工厂方法创建一个新的实例
* 这个片段使用提供的参数。
* *@param param1参数1。
* *@param param2参数2。
*
* @return一个新的片段CrimeFragment实例。
*/
// TODO:重命名和更改参数的类型和数量
public static CrimeListFragment newInstance(String param1, String param2) {
CrimeListFragment fragment = new CrimeListFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_crime_list, container, false);
//todo 注意理解此处的v是什么?和Activity中findViewById有什么相同和不同之处
mRecyclerview = v.findViewById(R.id.crime_recycleview);
mRecyclerview.setLayoutManager(new LinearLayoutManager(getActivity()));
CrimeLab crimeLab = CrimeLab.get(getActivity());
List<Crime> crimes = crimeLab.getCrimes();
mCimeAdapter = new CrimeAdapter(crimes);
mRecyclerview.setAdapter(mCimeAdapter);
return v;
}
//定义ViewHolder内部类
private class CrimeHolder extends RecyclerView.ViewHolder {
private TextView mTitle;
private TextView mDate;
private CheckBox mCheckBox;
private Crime mCrime;
public CrimeHolder(LayoutInflater inflater, ViewGroup container) {
super(inflater.inflate(R.layout.list_item_crime, container, false));
mTitle = itemView.findViewById(R.id.list_item_crime_title);
mDate = itemView.findViewById(R.id.list_item_crime_date);
mCheckBox = itemView.findViewById(R.id.list_item_crime_solved);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
CrimeFragment crimeFragment = CrimeFragment.newInstance(mCrime);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.list_fragment_container, crimeFragment)
.commit();
Toast.makeText(getActivity(), mCrime.getmId() + "clicked", Toast.LENGTH_SHORT).show();
}
});
}
//将crime显示在布局上
public void bind(Crime crime) {
mCrime = crime;
mTitle.setText(crime.getmTitle());
mDate.setText(crime.getmDate().toString());
mCheckBox.setChecked(crime.ismSolved());
}
}
//创建Adapter内部类
private class CrimeAdapter extends RecyclerView.Adapter<CrimeHolder> {
private List<Crime> crimes;
public CrimeAdapter(List<Crime> crimes) {
this.crimes = crimes;
}
//武装CrimeAdapter
@NonNull
@Override
public CrimeHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
return new CrimeHolder(layoutInflater, parent);
}
//调用bind(Crime)方法
@NonNull
@Override
public void onBindViewHolder(@NonNull CrimeHolder holder, int position) {
Crime crime = crimes.get(position);
holder.bind(crime);
}
@Override
public int getItemCount() {
return crimes.size();
}
}
}
(5)CrimeLab?
//单实例类
public class CrimeLab {
//保存该类的唯一实例
private static CrimeLab sCrimeLab;
//保存多个Crime的List容器
private List<Crime> mCrimes;
//暴露给外部的静态方法,生成或获取该类的唯一实例sCrimeLab
public static CrimeLab get(Context context) {
//确保实例的唯一性
if (sCrimeLab == null)
sCrimeLab = new CrimeLab(context);
return sCrimeLab;
}
//私有构造函数,使得外部无法new出该对象的实例
private CrimeLab(Context context) {
//实例化容器成员
mCrimes = new ArrayList<>();
//初始化100个crime表项
for (int i = 0; i < 100; i++) {
Crime crime = new Crime();
crime.setmTitle("Crime #" + i);
crime.setmSolved(i % 2 == 0);
mCrimes.add(crime);
}
}
public List<Crime> getCrimes() {
return mCrimes;
}
//根据UUID查找对应的crime表项
public Crime getCrime(UUID id) {
for (Crime crime : mCrimes) {
if (crime.getmId().equals(id))
return crime;
}
return null;
}
}
三、效果展示
?
|