10.1使用fragment argument+挑战练习

10.1使用fragment argument+挑战练习

贴出关键类

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

分类:

技术点:

相关文章: