Fragment

作者: Amy木婉清 | 来源:发表于2021-05-28 14:50 被阅读0次

    1.什么是Fragment

    Fragment的两个特性

    1)具备生命周期
    2)必须委托在activity中才能运行

    2.Fragment使用方法

    创建一个Activity:

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
    }
    

    创建一个fragment

    public class BlankFragment1 extends Fragment {
        private View root;
        private TextView textView;
        private Button button;
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            if (root == null) {
                root = inflater.inflate(R.layout.fragment_blank1, container, false);
            }
            textView = root.findViewById(R.id.textview);
            button = root.findViewById(R.id.button);
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    textView.setText("Yes,I am ,and you?");
                }
            });
            return root;
        }
    }
    

    fragment布局

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 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"
        android:orientation="vertical"
        tools:context=".BlankFragment1">
    
        <TextView
            android:id="@+id/textview"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:text="@string/hello_blank_fragment" />
        <Button
            android:text="how are you?"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:id="@+id/button"/>
    
    </LinearLayout>
    

    activtiy布局

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 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:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
    <fragment
        android:id="@+id/fragment1"//id必须有
        android:name="com.example.fragmenttest.BlankFragment1"//name必须有
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
    </LinearLayout>
    

    运行结果,点击按钮,内容变成Yes......

    在activity中添加两个fragment

    复制fragment1,命名fragment2

    public class BlankFragment2 extends Fragment {
        private View root;
        private TextView textView;
        private Button button;
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            if (root == null) {
                root = inflater.inflate(R.layout.fragment_blank1, container, false);
            }
            textView = root.findViewById(R.id.textview);
            button = root.findViewById(R.id.button);
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    textView.setText("Yes,I am ,and you?");
                }
            });
            return root;
        }
    }
    

    activtiy布局新增fragment

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 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:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
    <fragment
        android:id="@+id/fragment1"
        android:name="com.example.fragmenttest.BlankFragment1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        />
        <fragment
            android:id="@+id/fragment2"
            android:name="com.example.fragmenttest.BlankFragment2"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            />
    </LinearLayout>
    

    点击按钮后的运行结果:


    image.png
    Fragment的动态添加与管理

    创建Activity

    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Button btn1 = findViewById(R.id.btn1);
            btn1.setOnClickListener(this);
            Button btn2 = findViewById(R.id.btn2);
            btn2.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()){
                case R.id.btn1:
                    replaceFragment(new BlankFragment());
                    break;
                case R.id.btn2:
                    replaceFragment(new ItemFragment());
            }
        }
    
        //动态切换fragment
        private void replaceFragment(Fragment fragment) {
            FragmentManager fragmentManager  = getSupportFragmentManager();
            FragmentTransaction transaction = fragmentManager.beginTransaction();
            transaction.replace(R.id.framelayout,fragment);
            transaction.commit();
        }
    }
    

    创建布局

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 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:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <Button
            android:id="@+id/btn1"
            android:text="change"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <Button
            android:id="@+id/btn2"
            android:text="replace"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <FrameLayout
            android:id="@+id/framelayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/colorAccent"/>
    
    </LinearLayout>
    

    创建一个BlankFragment 一个listFragment


    image.png

    运行结果:
    点击按钮一change


    image.png

    点击按钮二replace


    image.png
    Activity与Fragment之间的通信

    原生方案:bundle
    在studio中输入logt,就会直接声明出来log中的TAG变量,即:

     private static final String TAG = "BlankFragment";
    

    1.从Activtiy发送信息到Fragment
    首先在MainActivtiy中的点击事件中添加Bundle

        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btn1:
                    Bundle bundle = new Bundle();
                    bundle.putString("message", "work hard no why");
                    BlankFragment blankFragment = new BlankFragment();
                    blankFragment.setArguments(bundle);
                    replaceFragment(blankFragment);
                    break;
            }
        }
    

    其次在Fragment的onCreate中获取

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Bundle bundle = getArguments();
            String string = bundle.getString("message");
            Log.d(TAG, "onCreate: "+string);
            if (getArguments() != null) {
                mParam1 = getArguments().getString(ARG_PARAM1);
                mParam2 = getArguments().getString(ARG_PARAM2);
            }
        }
    

    点击第一个按钮后,运行结果就会把刚刚传入的信息打印出来,即work hard no why.

    动态添加fragment步骤:

    1) 创建一个待处理的fragment
    2)获取FragmentManager,一般都是通过getSupportFragmentManager();
    3)开启一个事物transaction,一般调用fragmentManager的beginTransaction
    4)使用transaction进行fragmenet的替换
    5)提交事务 transaction.commit();

    fragment与Activity通信的接口方案

    Java语言中类与类之间通信的方案:

    1.接口回调

    首先创建一个接口:

    package com.example.fragmanager;
    
    /**
     * @author zwp
     * @description:
     * @date: 2021/5/26 14:28
     */
    public interface IFragmentCallBack {
        void sendMsgToActivity(String msg);
        String getMsgFromActivity(String msg);
    }
    

    在fragment中创建一个实现接口的类:

    package com.example.fragmanager;
    
    import android.os.Bundle;
    
    import androidx.fragment.app.Fragment;
    
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    
    public class BlankFragment extends Fragment {
        private static final String TAG = "BlankFragment";
        private View rootView;
    
        public BlankFragment() {
    
        }
    
        private IFragmentCallBack iFragmentCallBack;
    
        public void setIFragmentCallBack(IFragmentCallBack callBack) {
            iFragmentCallBack = callBack;
        }
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Bundle bundle = getArguments();
            String string = bundle.getString("message");
            Log.d(TAG, "onCreate: " + string);
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            if (rootView == null) {
                rootView = inflater.inflate(R.layout.fragment_blank, container, false);
            }
            Button btn = rootView.findViewById(R.id.btn);
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    iFragmentCallBack.sendMsgToActivity("hello,I am from fragment");//发送消息给activity
                }
            });
            return rootView;
        }
    
        @Override
        public void onResume() {
            super.onResume();
    
        }
    }
    

    Fragment的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=".BlankFragment">
    
        <!-- TODO: Update blank fragment layout -->
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="@string/hello_blank_fragment" />
    
        <Button
            android:id="@+id/btn"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="数据传递" />
    </FrameLayout>
    

    在Activtiy中引用

      @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btn1:
                    Bundle bundle = new Bundle();
                    bundle.putString("message", "work hard no why");
                    BlankFragment blankFragment = new BlankFragment();
                    blankFragment.setArguments(bundle);
                    //匿名內部类
                    blankFragment.setIFragmentCallBack(new IFragmentCallBack() {
                        @Override
                        public void sendMsgToActivity(String msg) {
                            Toast.makeText(MainActivity.this,msg,Toast.LENGTH_SHORT).show();
                        }
    
                        @Override
                        public String getMsgFromActivity(String msg) {
                            return null;
                        }
                    });
                    replaceFragment(blankFragment);
                    break;
            }
        }
    

    效果如下图所示,点击数据传递按钮:


    image.png
    从Activtiy中取消息

    Fragment

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            if (rootView == null) {
                rootView = inflater.inflate(R.layout.fragment_blank, container, false);
            }
            Button btn = rootView.findViewById(R.id.btn);
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // iFragmentCallBack.sendMsgToActivity("hello,I am from fragment");//发送消息给activity
                    String msg = iFragmentCallBack.getMsgFromActivity("从Activity取消息");
                    Toast.makeText(BlankFragment.this.getContext(), msg, Toast.LENGTH_SHORT).show();
                }
            });
            return rootView;
        }
    

    Activity

      @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btn1:
                    Bundle bundle = new Bundle();
                    bundle.putString("message", "work hard no why");
                    BlankFragment blankFragment = new BlankFragment();
                    blankFragment.setArguments(bundle);
                    //匿名內部类
                    blankFragment.setIFragmentCallBack(new IFragmentCallBack() {
                        @Override
                        public void sendMsgToActivity(String msg) {
                            Toast.makeText(MainActivity.this,msg,Toast.LENGTH_SHORT).show();
                        }
    
                        @Override
                        public String getMsgFromActivity(String msg) {
                            return "Hello,I am from Activity";
                        }
                    });
                    replaceFragment(blankFragment);
                    break;
                case R.id.btn2:
                    replaceFragment(new ItemFragment());
            }
        }
    

    运行结果:


    image.png
    通信的其他方案----->Eventbus LiveData
    Fragment的生命周期
    image.png
    onAttach、onDetach:Fragment与Activtiy之间的绑定和解绑
    因为Fragment依托于Activity,所以二者要进行绑定,使用结束之后要解绑。
    常遇见的问题:在Fragment中获取Activtiy内容,获取到变量为空的时候,根本原因就是没有把相应生命周期执行放在onAttach、onDetach之间执行。

    onCreate:fragment的创建------对Activtiy传过来的bundle进行解析
    onDestroy:fragment的销毁
    onCreateView:对UI的创建 Inflater.inflate......
    onActivtiyCreated:Activtiy已经创建了
    下面的几个生命周期与Activity相对应。

    Fragment生命周期

    1.打开页面
    onCreate()-->onCreateView()-->onActivityCreated()-->onStart()-->onResume()
    2.按下主屏键
    onpause()-->onStop()
    3.重新打开页面
    onStart()-->onResume()
    4.按后退键
    onPause()-->onStop()-->onDestroyView()-->onDestroy()-->onDetach()

    Fragment生命周期注意事项

    1.将来开发者会围绕fragment生命周期花很多时间来解决问题
    2.Fragment的使用一定是需要在生命周期函数onAttach与onDetach之间
    3.Fragment的使用一定要遵守生命周期管理的规则,在正确的地方写恰当的代码

    案例:Fragment与ViewPager滑动效果
    ViewPager的基本应用

    ViewPager2依赖:

        dependencies {
            implementation "androidx.viewpager2:viewpager2:1.0.0"
        }
    

    ViewPager2自带懒加载功能

    ViewPager使用流程

    1.定义ViewPager
    2.为ViewPager构建Adapter
    创建Activtiy,并在xml中引用viewPager
    activity

    package com.example.viewpagerandfragment;
    
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.viewpager2.widget.ViewPager2;
    
    import android.os.Bundle;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            ViewPager2 viewPager = findViewById(R.id.viewPager);
            ViewPageAdapter viewPageAdapter = new ViewPageAdapter();
            viewPager.setAdapter(viewPageAdapter);
        }
    }
    

    xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 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:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
        <androidx.viewpager2.widget.ViewPager2
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/viewPager"
            android:background="@color/colorAccent"/>
    </LinearLayout>
    

    创建一个item,用于显示布局内容

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/container">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:id="@+id/tvTitle"
            android:textColor="#ff4532"
            android:textSize="32sp"
            android:text="hello"/>
    </RelativeLayout>
    

    创建adapter:

    package com.example.viewpagerandfragment;
    
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.RelativeLayout;
    import android.widget.TextView;
    
    import androidx.annotation.NonNull;
    import androidx.recyclerview.widget.RecyclerView;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author zwp
     * @description:
     */
    public class ViewPageAdapter extends RecyclerView.Adapter<ViewPageAdapter.ViewPagerViewHolder> {
        private List<String> titles = new ArrayList<>();//每个页面显示的具体内容
        private List<Integer> colors = new ArrayList<>();//每个页面的颜色
        ViewPageAdapter(){
            titles.add("hello");
            titles.add("6");
            titles.add("7");
            titles.add("8");
            titles.add("9");
            titles.add("1");
            titles.add("2");
            titles.add("3");
            titles.add("4");
            titles.add("5");
            colors.add(R.color.white);
            colors.add(R.color.colorPrimary);
            colors.add(R.color.colorPrimaryDark);
            colors.add(R.color.black);
            colors.add(R.color.red);
            colors.add(R.color.colorAccent);
            colors.add(R.color.white);
            colors.add(R.color.red);
            colors.add(R.color.black);
            colors.add(R.color.colorPrimary);
        }
        @NonNull
        @Override
        public ViewPagerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            return new ViewPagerViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_pager,parent,false));
        }
    
        @Override
        public void onBindViewHolder(@NonNull ViewPagerViewHolder holder, int position) {
            holder.mTv.setText(titles.get(position));
            holder.mContainer.setBackgroundResource(colors.get(position));
        }
    
    
        @Override
        public int getItemCount() {
            return 10;
        }
    
        class ViewPagerViewHolder extends RecyclerView.ViewHolder{
    
            TextView mTv;
            RelativeLayout mContainer;
            public ViewPagerViewHolder(@NonNull View itemView) {
                super(itemView);
                mContainer = itemView.findViewById(R.id.container);
                mTv = itemView.findViewById(R.id.tvTitle);
            }
        }
    }
    

    运行结果即十个页面显示内容不一致并且可以左右切换滑动

    相关文章

      网友评论

        本文标题:Fragment

        本文链接:https://www.haomeiwen.com/subject/oseqsltx.html