• Android Studio教程07-Fragment的使用


    1. Fragment是什么

    • fragment表示 Activity 中的行为或用户界面部分。可以将多个片段组合在一个 Activity 中来构建多窗格 UI
    • fragment是activity的模块化组成部分
    • fragemnt性质:
      • 有自己的生命周期
      • 可以接收输入事件,并且可以在activity运行时添加或者删除片段
      • fragment必须依附在activity中(Activity暂停,fragment暂停,销毁也销毁)
      • activity运行时,可以独立操作每个片段,也可以在fragment和activity之间进行通信

    1.1. 设计原理和实例

    • 新闻应用可以使用一个片段在左侧显示文章列表,使用另一个片段在右侧显示文章 — 两个片段并排显示在一个 Activity 中,每个片段都具有自己的一套生命周期回调方法,并各自处理自己的用户输入事件。 因此,用户不需要使用一个 Activity 来选择文章,然后使用另一个 Activity 来阅读文章,而是可以在同一个 Activity 内选择文章并进行阅读

    2. 创建fragment

    通过创建Fragment子类

    • 创建fragment类
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.view.LayoutInflater;
    import android.view.ViewGroup;
    
    public class ArticleFragment extends Fragment {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            return inflater.inflate(R.layout.article_view, container, false);
        }
    }
    
    • 添加到activity布局中
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
    
        <fragment android:name="com.example.android.fragments.HeadlinesFragment"
                  android:id="@+id/headlines_fragment"
                  android:layout_weight="1"
                  android:layout_width="0dp"
                  android:layout_height="match_parent" />
    
        <fragment android:name="com.example.android.fragments.ArticleFragment"
                  android:id="@+id/article_fragment"
                  android:layout_weight="2"
                  android:layout_width="0dp"
                  android:layout_height="match_parent" />
    
    </LinearLayout>
    
    • 在activity中调用该fragment
    import android.os.Bundle;
    import android.support.v4.app.FragmentActivity;
    
    public class MainActivity extends FragmentActivity {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.news_articles);
        }
    }
    

    2.1. fragment的生命周期

    生命周期 含义 主要内容
    onCreate() 系统会在创建片段时调用此方法 初始化组件
    onCreateView() 系统会在片段首次绘制其用户界面时调用此方法。 要想为您的片段绘制 UI
    您从此方法中返回的 View 必须是片段布局的根视图
    onPause() 系统将此方法作为用户离开片段的第一个信号(但并不总是意味着此片段会被销毁)进行调用 确认在当前用户会话结束后仍然有效的任何更改

    2.2 添加用户界面:融入到Activity中

    • 步骤1: 创建一个布局文件example_fragment.xml
    • 步骤2: 在fragment类中加载布局
    public static class ExampleFragment extends Fragment {
      // container:您的片段布局将插入到的父 ViewGroup
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            return inflater.inflate(R.layout.example_fragment, container, false);
        }
    }
    
    • 步骤3: 在activity中添加片段
      • 方法1:直接在布局文件中添加:当系统创建此 Activity 布局时,会实例化在布局中指定的每个片段,并为每个片段调用 onCreateView() 方法,以检索每个片段的布局。
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <fragment android:name="com.example.news.ArticleListFragment"
                android:id="@+id/list"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="match_parent" />
        <fragment android:name="com.example.news.ArticleReaderFragment"
                android:id="@+id/viewer"
                android:layout_weight="2"
                android:layout_width="0dp"
                android:layout_height="match_parent" />
    </LinearLayout>
    
    • 方法2:通过编程添加
    // 必须使用 FragmentTransaction 中的 API
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    // 使用 add() 方法添加一个片段,指定要添加的片段以及将其插入哪个视图
    ExampleFragment fragment = new ExampleFragment();
    fragmentTransaction.add(R.id.fragment_container, fragment);
    // 调用 commit() 以使更改生效
    fragmentTransaction.commit();
    

    3. 管理fragment:FragmentManager

    FragmentManager的执行操作包括:

    • 通过 findFragmentById()(对于在 Activity 布局中提供 UI 的片段)或 findFragmentByTag()(对于提供或不提供 UI 的片段)获取 Activity 中存在的片段。
    • 通过 popBackStack()(模拟用户发出的返回命令)将片段从返回栈中弹出。
    • 通过 addOnBackStackChangedListener() 注册一个侦听返回栈变化的侦听器。

    3.1. 执行片段事务

    • Activity 中使用片段的一大优点是,可以根据用户行为通过它们执行添加、移除、替换以及其他操作。也称为事务
    • 可以将每个事务保存到由 Activity 管理的返回栈内,从而让用户能够回退片段更改(类似于回退 Activity)。
    // Create new fragment and transaction
    Fragment newFragment = new ExampleFragment();
    FragmentTransaction transaction = getFragmentManager().beginTransaction();
    
    // Replace whatever is in the fragment_container view with this fragment,
    // and add the transaction to the back stack 在返回栈中保留先前状态
    transaction.replace(R.id.fragment_container, newFragment);
    transaction.addToBackStack(null);
    
    // Commit the transaction
    transaction.commit();
    

    3.2. 与Activity通信

    • 片段可以通过getActivity() 访问 Activity 实例,并轻松地执行在 Activity 布局中查找视图等任务。
    • Activity 也可以使用 findFragmentById()findFragmentByTag(),通过从 FragmentManager 获取对 Fragment 的引用来调用片段中的方法
    // fragment - > activity
    View listView = getActivity().findViewById(R.id.list);
    // activity - > fragment  
    ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);
    

    (1) 创建对Activity的事件回调

    • 在片段内定义一个回调接口,并要求宿主 Activity 实现它。 当 Activity 通过该接口收到回调时,可以根据需要与布局中的其他片段共享这些信息。
    • 一个新闻应用的 Activity 有两个片段 — 一个用于显示文章列表(片段 A),另一个用于显示文章(片段 B)— 那么片段 A 必须在列表项被选定后告知 Activity,以便它告知片段 B 显示该文章。
    //fragment定义接口
    public static class FragmentA extends ListFragment {
        ...
        // Container Activity must implement this interface
        public interface OnArticleSelectedListener {
            public void onArticleSelected(Uri articleUri);
        }
        ...
    
        OnArticleSelectedListener mListener;
        ...
        // 确保宿主 Activity 实现此接口
        // 通过转换传递到 onAttach() 中的 Activity 来实例化 OnArticleSelectedListener 的实例
        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            try {
                mListener = (OnArticleSelectedListener) activity;
            } catch (ClassCastException e) {
                throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
            }
        }
        // 列表点击事件
        OnArticleSelectedListener mListener;
        ...
        @Override
        public void onListItemClick(ListView l, View v, int position, long id) {
            // Append the clicked item's row ID with the content provider Uri
            Uri noteUri = ContentUris.withAppendedId(ArticleColumns.CONTENT_URI, id);
            // Send the event and Uri to the host activity
            mListener.onArticleSelected(noteUri);
        }
        ...
    }
    

    4. fragment与activity的生命周期关系

    • Activity 的每次生命周期回调都会引发每个片段的类似回调。例如,当 Activity 收到 onPause() 时,Activity 中的每个片段也会收到 onPause()。

    5. 在Activity中动态添加fragment

    • 如需执行添加或移除片段等事务,您必须使用 FragmentManager 创建 FragmentTransaction,后者将提供添加、移除、替换片段以及执行其他片段事务所需的 API。
    • 如果您的 Activity 允许移除和替换片段,应在 Activity 的 onCreate() 方法执行期间为 Activity 添加初始片段。
    1. 采用以下方法为之前的布局添加片段:
    import android.os.Bundle;
    import android.support.v4.app.FragmentActivity;
    
    public class MainActivity extends FragmentActivity {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.news_articles);
    
            // Check that the activity is using the layout version with
            // the fragment_container FrameLayout
            if (findViewById(R.id.fragment_container) != null) {
    
                // However, if we're being restored from a previous state,
                // then we don't need to do anything and should return or else
                // we could end up with overlapping fragments.
                if (savedInstanceState != null) {
                    return;
                }
    
                // Create a new Fragment to be placed in the activity layout
                HeadlinesFragment firstFragment = new HeadlinesFragment();
    
                // In case this activity was started with special instructions from an
                // Intent, pass the Intent's extras to the fragment as arguments
                firstFragment.setArguments(getIntent().getExtras());
    
                // Add the fragment to the 'fragment_container' FrameLayout
                getSupportFragmentManager().beginTransaction()
                        .add(R.id.fragment_container, firstFragment).commit();
            }
        }
    }
    

    由于该片段已在运行时被添加到 FrameLayout 容器,可以从该 Activity 中移除该片段,并将其替换为其他片段。

    1. 替换片段:
    // Create fragment and give it an argument specifying the article it should show
    ArticleFragment newFragment = new ArticleFragment();
    Bundle args = new Bundle();
    args.putInt(ArticleFragment.ARG_POSITION, position);
    newFragment.setArguments(args);
    
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    
    // Replace whatever is in the fragment_container view with this fragment,
    // and add the transaction to the back stack so the user can navigate back
    transaction.replace(R.id.fragment_container, newFragment);
    transaction.addToBackStack(null);
    
    // Commit the transaction
    transaction.commit();
    

    6. 实例,新闻页面

    https://blog.csdn.net/zhaoyanga14/article/details/52166491

  • 相关阅读:
    css 边框添加四个角效果
    PS 怎么去掉噪点
    Packet Tracer——添加温度计
    zabbix监控mysql数据
    日常检测
    mysql的基本命令操作
    判断字典中是否有这个单词
    批量创建用户
    检测局域网ip存活状态
    spring boot gradle build:bootRepackage failed
  • 原文地址:https://www.cnblogs.com/haochen273/p/10298415.html
Copyright © 2020-2023  润新知