贴出关键类
ublic abstract class SinglesFragmentActivity extends AppCompatActivity {
public abstract Fragment createFramgnet();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
//创建一个新的fragment事务,执行一个fragment添加操作,然后提交该事务
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
/**
* 为什么要获取的fragment可能有了呢?设备旋转或回收内存时,Android系统会销
毁CrimeActivity,而后重建时,会调用CrimeActivity.onCreate(Bundle)方法。activity被
销毁时,它的FragmentManager会将fragment队列保存下来。这样,activity重建时,新的
FragmentManager会首先获取保存的队列,然后重建fragment队列,从而恢复到原来的状态。
*/
if (fragment == null) {
fragment = createFramgnet();
fm.beginTransaction()
//参数一:容器视图资源ID 参数二:创建的fragment
.add(R.id.fragment_container, fragment)
.commit();
}
}
}
public class CrimeListFragment extends Fragment {
private RecyclerView mCrimeRecyclerView;
private CrimeAdapter mCrimeAdapter;
private int mIndex;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
mIndex = savedInstanceState.getInt("index");
}
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_crime_list, container, false);
mCrimeRecyclerView = view.findViewById(R.id.crime_recycler_view);
/**
* 注意:没有LayoutManager的支持,不仅RecyclerView无法工作,还会导致应用崩溃
摆放的任务被委托给了LayoutManager。除了在屏幕上摆放列表项,LayoutManager还
负责定义屏幕滚动行为
*/
mCrimeRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
updateUI();
return view;
}
@Override
public void onResume() {
super.onResume();
// updateUI();
mCrimeAdapter.notifyItemChanged(mIndex);
}
private void updateUI() {
CrimeLab crimeLab = CrimeLab.get(getContext());
List<Crime> crimes = crimeLab.getCrimes();
if (mCrimeAdapter == null) {
mCrimeAdapter = new CrimeAdapter(getActivity(), crimes);
mCrimeRecyclerView.setAdapter(mCrimeAdapter);
mCrimeAdapter.notifyDataSetChanged();
} else {
mCrimeAdapter.notifyDataSetChanged();
}
}
public class CrimeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context mContext;
private List<Crime> mCrimes;
public static final String EXTRA_CRIME_ID =
"com.bignerdranch.android.criminalintent.crime_id";
public CrimeAdapter(Context context, List<Crime> crimes) {
this.mContext = context;
this.mCrimes = crimes;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
return new CrimeViewHolder(layoutInflater, parent, mContext);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {//主要作用是起显示的功能
Crime crime = mCrimes.get(position);
((CrimeViewHolder) holder).bind(crime);
}
@Override
public int getItemCount() {
return mCrimes.size();
}
}
//容纳View视图
class CrimeViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
Crime mCrime;
private TextView mTitleTextView;
private TextView mDateTextView;
private ImageView mSolvedImageView;
Context mContext;
private static final int REQUEST_CRIME = 1;
/**
* onCreateViewHolder(ViewGroup, int)方
* 法的调用并不频繁。一旦有了够用的ViewHolder,RecyclerView就会停止调用onCreate-
* ViewHolder(...)方法。随后,它会回收利用旧的ViewHolder以节约时间和内存
*/
public CrimeViewHolder(LayoutInflater inflater, ViewGroup parent, Context context) {
super(inflater.inflate(R.layout.list_item_crime, parent, false));
this.mContext = context;
mTitleTextView = (TextView) itemView.findViewById(R.id.crime_title);
mDateTextView = (TextView) itemView.findViewById(R.id.crime_data);
mSolvedImageView = (ImageView) itemView.findViewById(R.id.crime_solved);
itemView.setOnClickListener(this);
}
public void bind(Crime crime) {
mCrime = crime;
mTitleTextView.setText(mCrime.getTitle());
String date = (String) DateFormat.format("EEEE, MMMM dd, yyyy kk:mm", mCrime.getDate());
mDateTextView.setText(date);
mSolvedImageView.setVisibility(crime.isSolved() ? View.VISIBLE : View.GONE);
}
@Override
public void onClick(View view) {
//方式二:步骤一 跳转到CrimeActivity
Intent intent = CrimeActivity.newIntent(getActivity(), mCrime.getId());
startActivityForResult(intent, REQUEST_CRIME);
CrimeLab mCrimeLab = CrimeLab.get(getActivity());
// mIndex = mCrimeLab.getCrimeIndex(mCrime);
mIndex = getAdapterPosition();
}
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("index", mIndex);
}
}
public class CrimeActivity extends SinglesFragmentActivity {
public 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, CrimeActivity.class);
intent.putExtra(EXTRA_CRIME_ID, crimeId);
return intent;
}
@Override
public Fragment createFramgnet() {
//方式二:步骤二获取UUID值并传递给CrimeFragment
UUID crimeId = (UUID) getIntent()
.getSerializableExtra(EXTRA_CRIME_ID);
return CrimeFragment.newInstance(crimeId);
}
}
public class CrimeFragment extends Fragment {
/*方式二:使用fragment agrument方式获取数据
将crime ID存储在属于CrimeFragment的某个地方,而不是保存在
CrimeActivity的私有空间里。这样,无需依赖CrimeActivity的
intent内的extra,CrimeFragment 就能获取自己所需的extra数据。
属于fragment的“某个地方”实际就是它的argument bundle*/
public static CrimeFragment newInstance(UUID uuid) {
//方式二:步骤三 将argument放入bundle中,再附加给fragment。
Bundle args = new Bundle();
args.putSerializable(ARG_CRIME_ID, uuid);
CrimeFragment fragment = new CrimeFragment();
fragment.setArguments(args);
return fragment;
}
private Crime mCrime;
private EditText mTitleField;
private Button mDateButton;
private CheckBox mSolvedCheckBox;
private static final String ARG_CRIME_ID = "crime_id";
public static final String EXTRA_CRIME_ID =
"com.bignerdranch.android.criminalintent.crime_id";
/**
* Fragment.onCreateView(...)方法中的组件引用几乎等同于Activity.onCreate(Bundle)
* 方法的处理。唯一的区别是,你调用了fragment视图的View.findViewById(int)方法。以前使
* 用的Activity.findViewById(int)方法十分便利,能够在后台自动调用View.findViewById
* (int)方法,而Fragment类没有对应的便利方法,因此必须手动调用。
*
* @param savedInstanceState
*/
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mCrime = new Crime();
initBundleData();
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
//第一个参数是布局资源文件
//第二个参数是视图的父视图,我们通常需要父视图来正确配置组件。
//第三个参数告诉布局生成器是否将生成的视图添加给父视图。这里,传入了false参数,因为我们将以代码的方式添加视图。
View view = inflater.inflate(R.layout.fragment_crime, container, false);
initView(view);
mTitleField.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) {
//(代表用户输入)的toString()方法
mCrime.setTitle(charSequence.toString());
}
@Override
public void afterTextChanged(Editable editable) {
}
});
mTitleField.setText(mCrime.getTitle());
mSolvedCheckBox.setChecked(mCrime.isSolved());
mDateButton.setText(mCrime.getDate().toString());
//禁用Button按钮,确保它不会响应用户的点击。按钮应处于灰色状,让用户知道是不可以按的
mDateButton.setEnabled(false);
mSolvedCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
mCrime.setSolved(isChecked);
}
});
return view;
}
private void initBundleData() {
// fragment有2种方式获取intent数据
/*方式1、直接获取数据
只需几行简单的代码,就可让fragment直接从托管activity的intent中获取信息。
然而,这种方式破坏了fragment的封装。CrimeFragment不再是可复用的构建单元,
因为它现在由某个特定的activity托管着*/
// UUID uuid = (UUID) getActivity().getIntent().getSerializableExtra(EXTRA_CRIME_ID);
// mCrime = CrimeLab.get(getActivity()).getCrime(uuid);
//方式二:步骤四获取UUID的值
UUID uuid = (UUID) getArguments().getSerializable(ARG_CRIME_ID);
mCrime = CrimeLab.get(getActivity()).getCrime(uuid);
}
private void initView(View view) {
mTitleField = view.findViewById(R.id.crime_title);
mDateButton = view.findViewById(R.id.crime_date);
mSolvedCheckBox = view.findViewById(R.id.crime_solved);
}
}
Demo下载地址:
https://download.csdn.net/download/weixin_43953649/10875385