CrimeFragment的UI fragment进行管理

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
用户界面将由一个名为 CrimeFragment UI fragment 进行管理。 CrimeFragment
实例将通过一个名为 CrimeActivity activity 托管
CrimeActivity 视图由 FrameLayout 组件组成 FrameLayout 组件为 CrimeFragment 要显示
的视图安排了存放位置。
CrimeFragment 的视图由一个 LinearLayout 组件及一个 EditText 组件组成。
CrimeFragment 类中有一个存储 EditText 的成员变量 mTitleField mTitleField 上设有监
听器当 EditText 上的文字发生改变时用来更新模型层的数据。
FragmentActivity Activity 的子类具有新系统版本
Activity 类管理 fragment 的能力即便是在较早版本的 Android 设备上也可对 fragment 进行管理。

 创建CrimeActivity

托管 UI fragment

为托管 UI fragment activity 必须做到
        在布局中为fragment 的视图安排位置
        管理fragment 实例的生命周期。

 

 定义容器视图

修改activity_crime.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/fragmentContainer">
</FrameLayout>

创建 UI fragment

fragment 视图的布局文件 fragment_crime.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".CrimeFragment">

     <EditText
         android:id="@+id/crime_title"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:hint="请输入标题" />
</FrameLayout>

创建CrimeFragment


import android.os.Bundle;

import androidx.fragment.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.EditText;
import android.widget.Toast;

import yu.app.criminalintent.model.Crime;

/**
 *
 */
public class CrimeFragment extends Fragment {


    private Crime   mCrime;
    private EditText mTitleField;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         mCrime=new Crime();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View v=inflater.inflate(R.layout.fragment_crime, container, false);
        mTitleField = v.findViewById(R.id.crime_title);
        mTitleField.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence c, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence c, int start, int before, int count) {
                mCrime.setmTitle(c.toString());
                Toast.makeText(getContext(), c.toString(), Toast.LENGTH_SHORT).show();
            }

            @Override
            public void afterTextChanged(Editable editable) {

            }
        });

        // Inflate the layout for this fragment
        return v;
    }
}
Fragment.onCreateView(...) 方法中的组件引用几乎等同于 Activity.onCreate(...)
方法的处理。唯一的区别是我们调用了当前 fragment 视图的 View.findViewById(int) 方法。以前使
用的 Activity.findViewById(int) 方法十分便利能够在后台自动调用 View.findView
ById(int) 方法。而 Fragment 类没有对应的便利方法因此我们必须自己完成调用。
fragment 中监听器方法的设置和 activity 中的处理完全一样。 创建实现 TextWatcher 监听器接口的匿名内部类。 TextWatcher 有三种方法不过我们现在只需关注其中 onTextChanged(...) 方法。
onTextChanged(...) 方法中调用 CharSequence 代表用户输入的 toString() 方法。
该方法最后返回用来设置 Crime 标题的字符串。
CrimeFragment 类的代码实现部分完成了。但现在还不能运行应用查看用户界面和检验代
码。因为 fragment 无法将自己的视图显示在屏幕上。接下来我们首先要把 CrimeFragment 添加给
CrimeActivity。

添加 UI fragment FragmentManager

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;

import android.os.Bundle;

public class CrimeActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_crime);
        //获取碎片管理
        FragmentManager fm = getSupportFragmentManager();
        //获取碎片存放的容器
        Fragment f = fm.findFragmentById(R.id.fragmentContainer);
        if (f==null){
            //实例化碎片
            f=new CrimeFragment();
            //碎片管理开启事务添加实例化碎片到碎片存放容器中并提交事务
            fm.beginTransaction().add(R.id.fragmentContainer, f).commit();
        }

    }
}
fragment 事务被用来添加、移除、附加、分离或替换 fragment 队列中的 fragment 。这是使用
fragment 在运行时组装和重新组装用户界面的核心方式。 FragmentManager 管理着 fragment 事务
的回退栈。
FragmentManager.beginTransaction() 方法创建并返回 FragmentTransaction 实例。
FragmentTransaction 类使用了一个 fluent interface 接口方法通过该方法配置 FragmentTran
saction 返回 FragmentTransaction 类对象而不是 void 由此可得到一个 FragmentTransa
ction队列。
add(...) 方法是整个事务的核心部分并含有两个参数即容器视图资源 ID 和新创建的
CrimeFragment 。容器视图资源 ID 我们应该很熟悉了它是定义在 activity_crime.xml 中的
FrameLayout 组件的资源 ID 。容器视图资源 ID 主要有两点作用
  告知 FragmentManager fragment 视图应该出现在 activity 视图的什么地方
  FragmentManager 队列中 fragment 的唯一标识符。

升级Crime类


import java.util.Date;
import java.util.UUID;

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 getmID() {
        return mID;
    }

    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;
    }
}

更新fragment_crime.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".CrimeFragment">

    <LinearLayout
        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/mCrime_title"
             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" />

         <TextView
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:text="@string/crime_detail"
             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/isSolved"/>

    </LinearLayout>



</FrameLayout>

更新CrimeFragment

 

import android.os.Bundle;

import androidx.fragment.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.CompoundButton;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.Toast;

import java.text.DateFormat;
import java.text.SimpleDateFormat;

import yu.app.criminalintent.model.Crime;

/**
 *
 */
public class CrimeFragment extends Fragment {


    private Crime   mCrime;
    private EditText mTitleField;
    private Button mDateBtn;
    private CheckBox mSolvedCbox;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         mCrime=new Crime();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View v=inflater.inflate(R.layout.fragment_crime, container, false);
        mTitleField = v.findViewById(R.id.crime_title);
        mTitleField.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence c, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence c, int start, int before, int count) {
                mCrime.setmTitle(c.toString());
                Toast.makeText(getContext(), c.toString(), Toast.LENGTH_SHORT).show();
            }

            @Override
            public void afterTextChanged(Editable editable) {

            }
        });

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd E a HH:mm:ss");
        mDateBtn = v.findViewById(R.id.crime_date);
        mDateBtn.setText(dateFormat.format(mCrime.getmDate()));
        mDateBtn.setEnabled(false);

        mSolvedCbox = v.findViewById(R.id.crime_solved);
        mSolvedCbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                mCrime.setmSolved(b);
                Toast.makeText(getContext(), String.valueOf(mCrime.ismSolved()) , Toast.LENGTH_SHORT).show();
            }
        });

        // Inflate the layout for this fragment
        return v;
    }
}

使用ListFragment显示列表

应用的模型层将新增一个 CrimeLab 对象该对象是一个数据集中存储池用来存储 Crime 对象。
显示 crime 列表需在应用的控制层新增一个 activity 和一个 fragment CrimeListActivity
CrimeListFragment
CrimeListFragment ListFragment 的子类 ListFragment Fragment 的子类。
Fragment 内置列表显示支持功能。控制层对象间、控制层对象与 CrimeLab 对象间彼此交互进
行模型层数据的存取。
ArrayList<E> 是一个支持存放指定数据类型对象的 Java 有序数组类具有获取、新增及删除
数组中元素的方法。

创建CrimeLab


import android.content.Context;

import java.util.ArrayList;
import java.util.UUID;

public class CrimeLab {
    private ArrayList<Crime> mCrimes;

    private static CrimeLab crimeLab;
    private Context appContext;

    private CrimeLab(Context appContext){
        this.appContext=appContext;
        this.mCrimes=new ArrayList<>();

        //测试 先往数组列表中批量存入100个Crime对象
        for (int i=1;i<=100;i++){
            Crime c=new Crime();
            c.setmTitle("Crime标题#"+i);
            c.setmSolved(i%2==0);
            mCrimes.add(c);
        }

    }

    public static CrimeLab get(Context c){
        if (crimeLab==null){
            crimeLab = new CrimeLab(c.getApplicationContext());
        }
        return  crimeLab;
    }


    public ArrayList<Crime> getmCrimes() {
        return mCrimes;
    }

    public  Crime getCrime(UUID id){
        for (Crime c : mCrimes){
            if (c.getmID().equals(id)){
                return c;
            }
        }
        return null;
    }
}

创建CrimeListActivity


import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.fragment.app.Fragment;

import yu.app.criminalintent.base.SingleFragmentActivity;
import yu.app.criminalintent.fragment.CrimeListFragment;

public class CrimeListActivity extends SingleFragmentActivity {

    @Override
    protected Fragment createFragment() {
        return new CrimeListFragment();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_crime_list_list, container, false);

        return view;
    }
}

创建CrimeListFragment

 

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.ListFragment;

import java.util.ArrayList;

import yu.app.criminalintent.R;
import yu.app.criminalintent.base.SingleFragmentActivity;
import yu.app.criminalintent.model.Crime;
import yu.app.criminalintent.model.CrimeLab;

/**
 * A fragment representing a list of Items.
 */
public class CrimeListFragment extends ListFragment {

    private static final String TAG = "CrimeListFragment";
    private ArrayList<Crime> mCrimes;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mCrimes = CrimeLab.get(getActivity()).getmCrimes();

        ArrayAdapter<Crime> adapter = new ArrayAdapter<Crime>(getActivity(), android.R.layout.simple_expandable_list_item_1, mCrimes);
        setListAdapter(adapter);
    }

    @Override
    public void onListItemClick(@NonNull ListView l, @NonNull View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        Crime c = (Crime) getListAdapter().getItem(position);
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle("提示信息");
        builder.setMessage(c.toString());
        builder.setPositiveButton("确定",new DialogInterface.OnClickListener(){

            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                    //
            }
        });

        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {

                //
            }
        });

        AlertDialog alertDialog=builder.create();
        alertDialog.show();

    }
}

修改AndroidMainfest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <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/Theme.YuApp">
        <activity
            android:name=".CrimeListActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
        </activity>
    </application>

</manifest>

fragment_crime_list_list.xml布局文件

<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView 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:id="@+id/list"
    android:name="yu.app.criminalintent.fragment.CrimeListFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginLeft="16dp"
    android:layout_marginRight="16dp"
    app:layoutManager="LinearLayoutManager"
    tools:context=".fragment.CrimeListFragment"
    tools:listitem="@layout/fragment_crime_list" />

创建SingleFragmentActivity

 

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;

import yu.app.criminalintent.R;

/**
 * 通用fragment的抽象类
 */
public abstract class SingleFragmentActivity extends FragmentActivity {
    //该抽象方法可实例化新的fragmentSingleFragmentActivity的子类会实现该方法返回一个由activity托管的fragment实例
    protected  abstract  Fragment createFragment();

    @Override
    protected void onCreate( Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_crime);
        FragmentManager fm=getSupportFragmentManager();
        Fragment f = fm.findFragmentById(R.id.fragmentContainer);
        if (f==null){
            f=createFragment();
            fm.beginTransaction().add(R.id.fragmentContainer, f).commit();
        }
    }

    public abstract View onCreateView(LayoutInflater inflater, ViewGroup container,
                                      Bundle savedInstanceState);
}

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6