0


CrimeFragment的UI fragment进行管理

用户界面将由一个名为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主要有两点作用:

告知FragmentManagerfragment视图应该出现在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 {
    //该抽象方法可实例化新的fragment,SingleFragmentActivity的子类会实现该方法返回一个由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);
}
标签: android

本文转载自: https://blog.csdn.net/yushangyong/article/details/128720858
版权归原作者 人海中的海盗 所有, 如有侵权,请联系我们删除。

“CrimeFragment的UI fragment进行管理”的评论:

还没有评论