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 主要有两点作用:
  告知 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 {
    //该抽象方法可实例化新的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);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

人海中的海盗

你的打赏将是对我的激励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值