Android学习笔记(4)——探究碎片

第四章

补充:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3ICBbv0u-1627825748253)(C:\Users\过客\AppData\Roaming\Typora\typora-user-images\image-20210729155139748.png)]

4.1 碎片是什么

  1. 概述:碎片(Fragment)是一种可以嵌入在活动当中的UI片段,它能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用得非常广泛

  2. 平板使用碎片实现如下布局:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jFL96NbZ-1627825748256)(C:\Users\过客\AppData\Roaming\Typora\typora-user-images\image-20210729103100474.png)]

4.2 碎片的使用方式

4.2.1 碎片的简单实用
  1. 使用步骤:

    1. 创建碎片的布局:

      左碎片布局:

      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical">
      
          <Button
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:id="@+id/button"
              android:layout_gravity="center_horizontal"
              android:text="@string/button"/>
      
      </LinearLayout>
      

      右碎片布局:

      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical"
          android:background="#00ff00">
      
          <TextView
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_gravity="center_horizontal"
              android:textSize="20sp"
              android:text="@string/this_is_right_fragment"/>
      
      </LinearLayout>
      
    2. 为碎片布局文件创建对应的类,让此类继承Fragment类,重写onCreateView()方法,方法内部通过LayoutInflater的inflate()方法将刚才定义的布局动态加载进来

      左碎片类:

      package com.example.activity_tablet1;
      
      import android.os.Bundle;
      import android.view.LayoutInflater;
      import android.view.View;
      import android.view.ViewGroup;
      
      import androidx.fragment.app.Fragment;
      
      public class LeftFragment extends Fragment {
          @Override
          public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
              View view = inflater.inflate(R.layout.left_fragment,container,false);
              return view;
          }
      }
      
      

      右碎片类:

      package com.example.activity_tablet1;
      
      import android.os.Bundle;
      import android.view.LayoutInflater;
      import android.view.View;
      import android.view.ViewGroup;
      
      import androidx.fragment.app.Fragment;
      
      public class Right_fragment extends Fragment {
          @Override
          public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
              View view = inflater.inflate(R.layout.right_fragment, container, false);
              return view;
          }
      }
      
      
    3. 在著布局中加入碎片控件:

      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="horizontal">
      
          <fragment
              android:id="@+id/left_fragment"
              android:name="com.example.activity_tablet1.LeftFragment"
              android:layout_width="0dp"
              android:layout_height="match_parent"
              android:layout_weight="1" />
      
          <fragment
              android:id="@+id/right_fragment"
              android:name="com.example.activity_tablet1.Right_fragment"
              android:layout_width="0dp"
              android:layout_height="match_parent"
              android:layout_weight="1" />
      
      </LinearLayout>
      
4.2.2 动态添加碎片
  1. 实现步骤:

    1. 先创建碎片布局;

      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:background="#ffff00"
          android:orientation="vertical">
      
          <TextView
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_gravity="center_horizontal"
              android:textSize="20sp"
              android:text="@string/this_is_another_right_fragment"/>
      
      </LinearLayout>
      
    2. 创建碎片的动态加载类:

      package com.example.activity_tablet1;
      
      import android.os.Bundle;
      import android.view.LayoutInflater;
      import android.view.View;
      import android.view.ViewGroup;
      
      import androidx.fragment.app.Fragment;
      
      public class AnotherRightFragment extends Fragment {
      
          @Override
          public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
              View view = inflater.inflate(R.layout.another_right_fragment, container, false);
              return view;
          }
      }
      
      
    3. 实现碎片的添加替代功能:

      private void replaceFragment(Fragment fragment) {
              FragmentManager fragmentManager = getSupportFragmentManager();		//获取FragmentManager对象
              FragmentTransaction transaction = fragmentManager.beginTransaction();	//开启一个事务
              transaction.replace(R.id.right_layout, fragment);	//向容器中添加或者替换碎片
              transaction.commit();	//提交事物
          }
      

      动态添加碎片过程:

      1. 创建待添加的碎片实例。

      2. 获取FragmentManager,在活动中可以直接通过调用getSupportFragmentManager()方
        法得到。

      3. 开启一个事务,通过调用beginTransaction()方法开启。

      4. 向容器内添加或替换碎片,一般使用replace()方法实现,需要传人容器的id和待添加的碎片实例。

      5. 提交事务,调用commit()方法来完成。
        这样就完成了在活动中动态添加碎片的功能,重新运行程序,可以看到和之前相同的界面,
        然后点击一下按钮,效果如图4.6所示。

    4. 主活动中代码:

      package com.example.activity_tablet1;
      
      import androidx.appcompat.app.AppCompatActivity;
      import androidx.fragment.app.Fragment;
      import androidx.fragment.app.FragmentManager;
      import androidx.fragment.app.FragmentTransaction;
      
      import android.os.Bundle;
      import android.view.View;
      import android.widget.Button;
      
      public class MainActivity extends AppCompatActivity implements View.OnClickListener{
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
      
              Button button = (Button) findViewById(R.id.button);
              button.setOnClickListener(this);
              replaceFragment(new Right_fragment());	//加载初次显示碎片在左半边
          }
      
          @Override
          public void onClick(View view) {
              switch (view.getId()) {
                  case R.id.button:
                     replaceFragment(new AnotherRightFragment());		//点击按钮后对左半边碎片进行更新替换
                     break;
                  default:
                      break;
              }
          }
      
          private void replaceFragment(Fragment fragment) {
              FragmentManager fragmentManager = getSupportFragmentManager();
              FragmentTransaction transaction = fragmentManager.beginTransaction();
              transaction.replace(R.id.right_layout, fragment);
              transaction.commit();
          }
      }
      
4.2.3 在碎片中模拟回收栈
  1. 实现方法:

    FragmentTransaction 中提供了一个addToBackStack()方法,可以用于将一个
    事务添加到返回栈中,修改MainActivity中的代码,可实现按back时返回上层碎片的功能,类似活动跳转的返回过程。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0Qia7o3k-1627825748257)(C:\Users\过客\AppData\Roaming\Typora\typora-user-images\image-20210729162401224.png)]

4.2.4 碎片和活动之间进行通信
  1. 在活动中得到相应碎片的实例,FragmentManager 提供了一个类似于findViewById()
    的方法,专门用于从布局文件中获取碎片的实例,代码如下所示:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wglIvck2-1627825748260)(C:\Users\过客\AppData\Roaming\Typora\typora-user-images\image-20210729163537995.png)]

  2. 在碎片中获得活动,在每个碎片中都可以通过调用getActivity( )方法来得到和当前碎片相关联的活
    动实例,代码如下所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3aEJ0KC9-1627825748261)(C:\Users\过客\AppData\Roaming\Typora\typora-user-images\image-20210729164649051.png)]

4.3 碎片的生命周期

4.3.1 碎片的状态和回调
  1. 碎片的状态:

    1. 运行状态

      当一个碎片是可见的,并且它所关联的活动正处于运行状态时,该碎片也处于运行状态。

    2. 暂停状态

      当一个活动进人暂停状态时(由于另一个未占满屏幕的活动被添加到了栈顶),与它相关联的可见碎片就会进人到暂停状态。

    3. 停止状态

      当一个活动进入停止状态时,与它相关联的碎片就会进入到停止状态,或者通过调用
      FragmentTransaction的remove()、 replace()方法将碎片从活动中移除,但如果在事务提交之前调用addToBackStack()方法,这时的碎片也会进入到停止状态。总的来说,进人停止状态的碎片对用户来说是完全不可见的,有可能会被系统回收。

    4. 销毁状态

      碎片总是依附于活动而存在的,因此当活动被销毁时,与它相关联的碎片就会进人到销毁状态。或者通过调用FragmentTransaction 的remove() 、replace()方 法将碎片从活动中移除,但在事务提交之前并没有调用addToBackStack()方法,这时的碎片也会进人到销毁状态。

  2. 碎片几乎含有活动的所有回调方法,此外碎片还提供了一些附加的回调方法:

    1. onAttach()。当碎片和活动建立关联的时候调用。
    2. onCreateView()。为碎片创建视图(加载布局)时调用。
    3. onActivityCreated()。确保与碎片相关联的活动一定已经创建完毕的时候调用。
    4. onDestroyView()。当与碎片关联的视图被移除的时候调用。
    5. onDetach()。当碎片和活动解除关联的时候调用。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pj2UlIck-1627825748262)(C:\Users\过客\AppData\Roaming\Typora\typora-user-images\image-20210729170203558.png)]

4.3.2 体验碎片的生命周期
  1. 代码如下:

    package com.example.activity_tablet1;
    
    import android.content.Context;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    import androidx.fragment.app.Fragment;
    
    public class RightFragment extends Fragment {
        private static final String TAG = "RightFragment";
    
        @Override
        public void onAttach(Context context) {
            super.onAttach(context);
            Log.d(TAG, "onAttach");
        }
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Log.d(TAG, "onCreate");
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            Log.d(TAG, "onCreateView");
            View view = inflater.inflate(R.layout.right_fragment, container, false);
            return view;
        }
    
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            Log.d(TAG, "onActivityCreated");
        }
    
        @Override
        public void onResume() {
            super.onResume();
            Log.d(TAG, "onResume");
        }
    
        @Override
        public void onPause() {
            super.onPause();
            Log.d(TAG, "onPause");
        }
    
        @Override
        public void onStop() {
            super.onStop();
            Log.d(TAG, "onStop");
        }
    
        @Override
        public void onDestroyView() {
            super.onDestroyView();
            Log.d(TAG, "onDestroyView");
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            Log.d(TAG, "onDestroy");
        }
    }
    
    

    流程:

    1. 当RightFragment 第一次被加载到屏幕上时,会依次执行onAttach(),onCreate(),onCreateView(), onActivityCreated(),onStart ()和onResume()方法。

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SNtZXe2U-1627825748263)(C:\Users\过客\AppData\Roaming\Typora\typora-user-images\image-20210729172640311.png)]

    2. 点击LeftFragment中的按钮,由于AnotherRightFragment替换了RightFragment, 此时的RightFragment进入了停止状态
      因此onPause(),onStop( )和onDestroyView( )方法会得到执行。当然如果在替换的时候没有调用addToBackStack() 方法,此时的RightFragment 就会进人销毁状态,onDestroy()和
      onDetach()方法就会得到执行。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-howbB04h-1627825748263)(C:\Users\过客\AppData\Roaming\Typora\typora-user-images\image-20210729173039125.png)]

    1. 接着按下Back键,RightFragment 会重新回到屏幕,由于RightFragment 重新回到了运行状态,因此onActivityCreated()、 onStart ()和
      **onResume()**方法会得到执行。注意此时onCreate()和onCreateView()方法并不会执行,因为我们借助了addToBackStack()方法使得RightFragment和它的视图并没有销毁。

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tCrOkUL8-1627825748264)(C:\Users\过客\AppData\Roaming\Typora\typora-user-images\image-20210729173239642.png)]

    2. 再次按下Back键退出程序,依次会执行**onPause(),onStop(),onDestroyView(),onDestroy( )和onDetach()**方法,最终将活动和碎片一起销毁。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HxsdpG98-1627825748265)(C:\Users\过客\AppData\Roaming\Typora\typora-user-images\image-20210729173414208.png)]

4.4 动态加载布局的技巧

4.4.1 使用限定符
  1. 程序可以通过屏幕大小和限定符相匹配的模式为当前屏幕匹配最为合适的布局文件进行加载,文件夹后所跟的为此布局文件的限定符

    限定符:

    屏幕特性限定符描述
    大小small提供给小屏幕设备的资源
    大小normal提供给中等屏幕设备的资源
    大小large提供给大屏幕设备的资源
    大小xlarge提供给超大屏幕设备的资源
    分辨率ldpi提供给低分辨率设备的资源(120dpi以下)
    分辨率mdpi提供给中分辨率设备的资源(120dpi~160dpi)
    分辨率hdpi提供给高分辨率设备的资源(160dpi~240dpi)
    分辨率xhdpi提供给超高分辨率设备的资源(240dpi~320dpi)
    分辨率xxhdpi提供给超超高分辨率设备的资源(320dpi~480dpi)
    方向land提供给横屏设备的资源
    方向port提供给竖屏设备的资源
4.4.2 使用最小宽度限定符
  1. 使用:在res目录下新建layout-sw600dp文件夹,然后在这个文件夹下新建activity_ main.xml 布局,(swxxxdp,中间数字控制设备宽度,当设备宽度到达此宽度时就使用此布局)

    如:同一程序用手机打开为:(手机宽度未到达600dp,加载默认文件夹下activity_main布局)

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ck5bGlYs-1627825748265)(C:\Users\过客\AppData\Roaming\Typora\typora-user-images\image-20210729213237769.png)]

    使用平板打开为:(宽度大于600dp,加载layout-sw600dp文件夹下activity_main布局)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rnRPpwne-1627825748266)(C:\Users\过客\AppData\Roaming\Typora\typora-user-images\image-20210729213336504.png)]

4.5 碎片的最佳实践——一个简易版的新闻应用

  1. 设计两个布局,一个适用于平板等大屏设备,一个适用于手机等小屏设备

    1. 平板设计思路:左侧为新闻标题栏,右侧为新闻内容,点击左侧标题栏标题更新右侧内容栏的内容

      效果展示;

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dh1PwShw-1627825748267)(C:\Users\过客\AppData\Roaming\Typora\typora-user-images\image-20210730162717555.png)]

    2. 手机设计思路:全屏自上而下显示新闻标题栏,点击标题栏进行页面跳转,跳转至新闻内容页面(活动的跳转)

      效果展示:

      标题栏:

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cGC30b3X-1627825748268)(C:\Users\过客\AppData\Roaming\Typora\typora-user-images\image-20210730163036520.png)]

      内容栏:

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aiteCG74-1627825748268)(C:\Users\过客\AppData\Roaming\Typora\typora-user-images\image-20210730163128011.png)]

  2. 创建News类用于存储新闻信息:

    package com.example.fragmentbestpractice;
    
    public class News {
        private String title;
        private String content;
    
        public String getTitle() {
            return title;
        }
    
        public String getContent() {
            return content;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
    }
    
    
  3. 创建标题和内容栏碎片的布局文件:

    标题:(标题的控件为一个RecyclerView用于滚动显示标题)

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <androidx.recyclerview.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/news_title_recycler_view"/>
    
    </LinearLayout>
    

    内容:(布局里嵌套一个LinearLayout布局,此布局中放置两个TextView,一个用于显示标题,一个用于显示内容,两个View充当分割线)

    <?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">
    
        <LinearLayout
            android:id="@+id/visibility_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:visibility="invisible">
    
            <TextView
                android:id="@+id/news_title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:padding="10dp"
                android:textSize="20sp" />
    
            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="#000" />
    
            <TextView
                android:id="@+id/news_content"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:padding="15dp"
                android:textSize="18sp" />
    
        </LinearLayout>
    
        <View
            android:layout_width="1dp"
            android:layout_height="match_parent"
            android:layout_alignParentStart="true"
            android:layout_alignParentLeft="true"
            android:background="#000" />
    
    </RelativeLayout>
    
  4. 创建两个碎片的加载类:

    标题:(适配器以内部类的形式设置在此类当中)

    package com.example.fragmentbestpractice;
    
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    import androidx.fragment.app.Fragment;
    import androidx.recyclerview.widget.LinearLayoutManager;
    import androidx.recyclerview.widget.RecyclerView;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    
    public class NewsTitleFragment extends Fragment {
        private boolean isTwoPane;
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.news_title_frag, container , false);	//动态加载碎片
    
            RecyclerView newsTitleRecyclerView = (RecyclerView) view.findViewById(R.id.news_title_recycler_view);
            LinearLayoutManager layoutManager =new LinearLayoutManager(getActivity());
            newsTitleRecyclerView.setLayoutManager(layoutManager);
            NewsAdapter adapter = new NewsAdapter(getNews());
            newsTitleRecyclerView.setAdapter(adapter);
    
            return view;
        }
    
        public List<News> getNews() {	//初始化新闻内容信息
            List<News> newsList = new ArrayList<>();
            for(int i = 1 ; i <= 50; i++) {
                News news = new News();
                news.setTitle("This is title" + i);
                news.setContent(getRandomLengthContent("This is news content" + i + "."));
                newsList.add(news);
            }
            return newsList;
        }
    
        private String getRandomLengthContent(String content) {		//初始化新闻内容信息
            Random random = new Random();
            int length = random.nextInt(20) + 1;
            StringBuilder builder = new StringBuilder();
            for(int i = 0; i < length; i++) {
                builder.append(content);
            }
            return builder.toString();
        }
    
        @Override
        public void onStart() {		//判断当前加载方式为单页加载还是双叶加载
            super.onStart();
            if(getActivity().findViewById(R.id.news_content_layout) != null) {
                isTwoPane = true;	//用于调整内容显示布局的可见性
            }else {
                isTwoPane = false;
            }
        }
    
        class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.ViewHolder> {	//创建适配器内部类
            private List<News> mNewsList;
    
            class ViewHolder extends RecyclerView.ViewHolder {
                TextView newsTitleText;
    
                public ViewHolder(View view) {
                    super(view);
                    newsTitleText = (TextView) view.findViewById(R.id.news_title);
                }
            }
    
            public NewsAdapter(List<News> newsList) {
                mNewsList = newsList;
            }
    
            @NonNull
            @Override
            public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.news_item,parent,false);
    
                final ViewHolder Holder = new ViewHolder(view);
                view.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        News news = mNewsList.get(Holder.getAdapterPosition());
                        if(isTwoPane) {	//是双叶显示就刷新内容布局,显示新闻内容
                            NewsContentFragment newsContentFragment = (NewsContentFragment) getFragmentManager()
                                    .findFragmentById(R.id.news_content_fragment);
                            newsContentFragment.refresh(news.getTitle(), news.getContent());
                        }else {	//不是则进行活动的跳转,进入下一活动进行新闻内容的显示
                            NewsContentActivity.actionStart(getActivity(), news.getTitle(), news.getContent());
                        }
                    }
                });
                return Holder;
            }
    
            @Override
            public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
                News news = mNewsList.get(position);
                holder.newsTitleText.setText(news.getTitle());
            }
    
            @Override
            public int getItemCount() {
                return mNewsList.size();
            }
        }
    }
    
    

    内容:

    package com.example.fragmentbestpractice;
    
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    import androidx.fragment.app.Fragment;
    
    public class NewsContentFragment extends Fragment {
        private View view;
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            view = inflater.inflate(R.layout.news_content_frag, container, false);	//动态加载碎片
            return view;
        }
    
        public void refresh(String newsTitle, String newsContent) {	//刷新内容信息
            View visibilityLayout = view.findViewById(R.id.visibility_layout);
            visibilityLayout.setVisibility(View.VISIBLE);
            TextView newsTitleText = (TextView) view.findViewById(R.id.news_title);
            TextView newsContentText = (TextView) view.findViewById(R.id.news_content);
            newsContentText.setText(newsContent);
            newsTitleText.setText(newsTitle);
        }
    }
    
  5. 创建RecyclerView的子项布局:(为一个TextView布局)

    <?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
    
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/news_title"
        android:lines="1"
        android:ellipsize="end"
        android:textSize="18sp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:paddingTop="15dp"
        android:paddingBottom="15dp"
        />
    
  6. 创建新闻内容布局将内容碎片加载进来用于单屏时显示,(活动跳转,跳转后则使用此布局)

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <fragment
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:name="com.example.fragmentbestpractice.NewsContentFragment"
            android:id="@+id/news_content_fragment"/>
    
    </LinearLayout>
    
  7. 在默认主布局中加载标题碎片(小屏时使用此布局)

    <?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:orientation="horizontal"
        >
    
        <fragment
            android:id="@+id/news_title_fragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:name="com.example.fragmentbestpractice.NewsTitleFragment"	//此碎片为标题
            />
    
    </FrameLayout>
    
  8. 在自定义大屏文件夹下的布局文件加载碎片(文件夹使用限定符—sw600dp表示当屏幕宽度超过600dp时使用该布局为主布局):

    <?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:layout_width="0dp"
            android:layout_height="match_parent"
            android:id="@+id/news_title_fragment"	
            android:name="com.example.fragmentbestpractice.NewsTitleFragment"	//加载标题碎片,占比1/4
            android:layout_weight="1"/>	
    
        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="3"	
            android:id="@+id/news_content_layout">
    
            <fragment
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:name="com.example.fragmentbestpractice.NewsContentFragment"		//加载内容suip,占比3/4
                android:id="@+id/news_content_fragment"/>
    
        </FrameLayout>
    
    </LinearLayout>
    
  9. 创建单屏点击标题时活动的跳转活动类

    package com.example.fragmentbestpractice;
    
    import androidx.appcompat.app.AppCompatActivity;
    
    import android.content.Context;
    import android.content.Intent;
    import android.os.Bundle;
    
    public class NewsContentActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.news_content);
    
            String newsTitle = getIntent().getStringExtra("news_title");	//获取上一活动传递的新闻信息
            String newsContent = getIntent().getStringExtra("news_content");
    
            NewsContentFragment newsContentFragment = (NewsContentFragment) getSupportFragmentManager()
                    .findFragmentById(R.id.news_content_fragment);	//活动中联系碎片,对碎片的信息进行更新
            newsContentFragment.refresh(newsTitle, newsContent);
        }
    
        public static void actionStart(Context context, String newsTitle, String newsContent) {		//在本活动创建上一活动向本活动传递信息的方法
            Intent intent = new Intent(context, NewsContentActivity.class);
            intent.putExtra("news_title", newsTitle);
            intent.putExtra("news_content", newsContent);
            context.startActivity(intent);
        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值