碎片及其使用方式

碎片及其使用方式

是一种可以嵌入在活动中的UI片段,可以让程序更加合理和充分利用大屏幕的控件,在平板上应用广泛

碎片的简单用法

在一个活动中添加两个碎片,并让这两个碎片评分活动空间

新建一个左侧碎片布局left_fragment.xml(添加了一个button按钮并局中)

新建一个右侧碎片布局right_fragment.xml(添加了TextView用来显示一段文本)

新建一个LeftFragment类,使其继承Frgment,选择support-v4库中的Fragment,代码如下:

其实有两个不同包的fragment可以选择,选择support-v4库中的Fragment可以让碎片在所有的Android系统版本中保持功能一致性

``

public class LeftFragment extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saveInstanceState){
        View view=inflater.inflate(R.layout.left_fragment,container,false);
        return view;
        
    }
}

此方法通过LayouInflater的inflate()方法将刚才定义的left_fragment布局加载进来。

新建一个RightFragment,代码与LeftFragment类似,只是引入的是right_fragment.xml

接下来修改activity_main.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"
    android:orientation="horizontal"
    tools:context=".MainActivity">
    <fragment
        android:id="@+id/left_fragment"
            <!--name来显示指明要添加的碎片类名,注意将类的包名加上-->
        android:name="com.example.paddemo.LeftFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"/>
    <fragment
        android:id="@+id/right_fragment"
        android:name="com.example.paddemo.RightFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"/>
</LinearLayout>

动态添加碎片

在上方基础上新建another_right_fragment.xml,代码与right_fragment.xml基本相同,只是背景颜色改成了黄色显示文字替换。

新建AnotherRightFragment作为另一个右侧碎片,代码与LeftFragment类似,只是引入的是another_right_fragment.xml

修改antivity_main.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"
    android:orientation="horizontal"
    tools:context=".MainActivity">
    <fragment
        android:id="@+id/left_fragment"
        android:name="com.example.paddemo.LeftFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"/>
        <!--添加了这里-->
    <FrameLayout
        android:id="@+id/right_layout"
        android:layout_height="match_parent"
        android:layout_width="0dp"
        android:layout_weight="1">
    </FrameLayout>
</LinearLayout>

在代码中向FrameLayout里添加内容,从而实现动态添加碎片的功能,修改MainActivity代码如下:

``

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 RightFragment());
    }
    public void onClick(View v){
        switch (v.getId()){
            case R.id.button:
                replaceFragment(new AnotherRightFragment());
                break;
            default:
                break;
        }
    }
    private void replaceFragment(Fragment fragment){
        // 获取FragmentManager
        FragmentManager fragmentManager=getSupportFragmentManager();
        // 开启一个事务
        FragmentTransaction transaction=fragmentManager.beginTransaction();
        // 向容器内添加或替换碎片,需要传入容器的id和待添加的碎片实例
        transaction.replace(R.id.right_layout,fragment);
        // 提交事务
        transaction.commit();
    }
}

首先为左侧碎片中的按钮注册了点击事件,然后调用replaceFragment()方法动态添加了RightFragment这个碎片,点击左侧碎片按钮时又会调用replaceFragment()将右侧碎片替换成AnotherRightFragment

综上,动态添加碎片主要分为5步:

  1. 创建待添加的碎片实例
  2. 获取FragmentManager,在活动中直接调用getSupportFragmentManager()得到
  3. 开启一个事务,通过调用beginTransaction()方法开启
  4. 向容器内添加或替换碎片,一般使用replace()方法实现,需要传入容器的id和待添加的碎片实例
  5. 提交事务由commit()方法来完成,这样就可完成动态添加碎片

在碎片中模拟返回栈

通过按钮添加碎片后按下Back键会退出,修改此功能,使得按下back键可以返回上一个碎片

FramentTransaction中提供了一个addToBackStack方法,可以用于将一个事务添加到返回栈中,修改MainActivity中的replaceFragment方法,如下:

``

private void replaceFragment(Fragment fragment){
    FragmentManager fragmentManager=getSupportFragmentManager();
    FragmentTransaction transaction=fragmentManager.beginTransaction();
    transaction.replace(R.id.right_layout,fragment);
    transaction.addToBackStack(null);
    transaction.commit();
}

在提交事务前我们调用了FragmentTransaction的addToBackStack()方法,它可以接收一个名字用于描述返回栈的状态,一般传入null即可,重新运行程序发现程序没有退出,而是回到了RightFragment界面,再次按下Back键,RightFragment也会,再按,程序才会退出

碎片和活动之间通信

FragmentManager提供了一个类似于findViewById()的方法,专门用于

从布局文件中获取碎片的实例,代码如下:

RightFragment rightFragment=(RightFragment)getFragmentManager().findFragmentById(R.id.right_fragment);

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

MainActivity activity=(MainActivity)getActivity();

这样在碎片中调用活动的方法就很简单,另外当碎片中需要使用Context对象时也可以使用getActivity()方法,因为获取到的活动本身就是一个Context对象

碎片的生命周期

碎片的状态

运行状态

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

暂停状态

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

停止状态

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

销毁状态

活动被销毁时,与其相关联的碎片就会进入到销毁状态,或者通过调用FragmentTransaction的remove()、replace()方法将碎片从活动中移除,但是提交事务前并没有调用addToBackStack()方法,这是的碎片也会进入到销毁状态

碎片的回调

活动中有的回调方法,碎片中几乎都有,下面介绍一些附加的回调方法

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6ulv3QZG-1618189125321)(D:\学习\Android\笔记\4photo\碎片的活动周期.png)]

体验碎片的活动周期

修改RightFragment中的代码:

``

public class RightFragment extends Fragment {
    public static final String TAG="RightFragment";
    public void onAttach(Context context){
        super.onAttach(context);
        Log.d(TAG,"onAttach");
    }
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        Log.d(TAG,"onCreate");
    }
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saveInstanceState){
        Log.d(TAG,"onCreatedView");
        View view=inflater.inflate(R.layout.right_fragment,container,false);
        return view;
    }
    public void onActivityCreated(Bundle savedInstanceState){
        super.onActivityCreated(savedInstanceState);
        Log.d(TAG,"onActivityCreated");
    }
    public void onStart(){
        super.onStart();
        Log.d(TAG,"onStart");
    }
    public void onResume(){
        super.onResume();
        Log.d(TAG,"onResume");
    }
    public void onPause(){
        super.onPause();
        Log.d(TAG,"onPause");
    }
    public void onStop(){
        super.onStop();
        Log.d(TAG,"onStop");
    }
    public void onDestroyView(){
        super.onDestroyView();
        Log.d(TAG,"onDestroyView");
    }
    public void onDestroy(){
        super.onDestroy();
        Log.d(TAG,"onDestroy");
    }
    public void onDetach(){
        super.onDetach();
        Log.d(TAG,"onDetach");
    }
}

运行程序后查看打印信息可以看到,当RighrFragment第一次被加载到屏幕上时,会依次执行onAttach()、onCreate()、onVreateView、onActivityVreated()、onStart()和onResume()方法,然后点击LeftFragment中的按钮,此时由于AnotherRightFragment替换了RightFragment、此时的RightFragment进入了暂停状态,因此onPause()、onStop()和onDestroyView()会依次执行。如果替换的时候没有调用addToBackStack()方法,此时的RightFFragment就会进入销毁状态,onDestroy()和onDetach()方法就会得到执行

接着按下Back键,RightFragment会重新回到屏幕,因此ActivityVreated()、onStart()和Resume()方法会得到执行,此时onCreate()和onCreateView()并不会执行,因为我们借助了addToBackStack()方法的使得RightFragment和它的视图并没有销毁

动态加载布局的技巧

使用限定符

可以在运行时判断程序应该使用单页还是双页模式

修改activity_main.xml文件,将多于代码删掉,只剩下一个左碎片,并使它充满整个父布局。接着在res目录下新建layout-large文件夹,在这个文件夹下新建一个布局,也叫做activity_main.xml,代码如下:

``

<?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:id="@+id/left_fragment"
        android:layout_width="0dp"
        android:name="com.example.paddemo.LeftFragment"
        android:layout_height="match_parent"
        android:layout_weight="1"/>
    <fragment
        android:id="@+id/right_fragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="3"
        android:name="com.example.paddemo.RightFragment"/>
        
</LinearLayout>

layout/activity_main布局只包含了一个碎片,即单页模式,而layout-large/activity_main布局包含了两个碎片,即双页模式。其中large就是一个限定符,那些屏幕被认为是large的设备就会自动加载layout-large文件夹下的布局,而屏幕小的设备则还是会加载layout文件夹下的布局

然后把MainActivity中replaceFragment()方法里的代码注释掉,并在平板模拟器上重新运行程序,是双页模式,在手机模拟器上则是单页模式

Android中一些常见的限定符可以参考下表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fLHdbFK8-1618189125325)(D:\学习\Android\笔记\4photo\限定符.png)]

使用最小宽度限定符

有时候我们希望可以更加灵活地为不同设备加载布局,不管是不是被系统认定为large,这时就可以使用最小宽度限定符。

最小限定符允许我们对屏幕的宽度指定一个最小值(以dp为单位)

,然后以这个最小值为临界点,屏幕宽度大于这个值的设备就加载一个布局,小于这个值就加载另一个布局

在res目录下新建layout-sw600dp文件夹,然后在这个文件夹下新建activity_main.xml布局,代码如下:

``

<?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:id="@+id/left_fragment"
        android:layout_width="0dp"
        android:name="com.example.paddemo.LeftFragment"
        android:layout_height="match_parent"
        android:layout_weight="1"/>
    <fragment
        android:id="@+id/right_fragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="3"
        android:name="com.example.paddemo.RightFragment"/>
</LinearLayout>

这意味着当程序运行在屏幕宽度大于600dp的设备上时会加载layout-sw600dp/activity_main布局,小于600dp时仍然加载layout/activity_main布局

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

新建一个FragmentBestPractice项目,由于会使用RecyclerView,因此需要在app/build.gradle中添加依赖库,如下所示:

implementation 'com.android.support:recyclerview-v7:24.2.1'

新建类News,代码如下:

``

public class News {
    // 表示新闻标题
    private  String title;
    // 表示新闻内容
    private String content;
    public String getTitle(){
        return title;
    }
    public void setTitle(String title){
        this.title=title;
    }
    public String getContent(){
        return content;
    }
    public void setContent(String content){
        this.content=content;
    }
}

接下来新建布局news_content_frag.xml,用作新闻内容的布局:

<?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: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_alignParentLeft="true" android:background="#000"/> </RelativeLayout>

新闻内容布局分为两个部分,头部部分显示新闻标题,正文部分显示新闻内容,中间使用一条细线隔开,这里的细线由View来实现,将View的宽或高设置成1dp,再通过background属性给细线设置一下颜色即可

再新建一个NewsContentFragment类,继承Fragment,代码如下:

``

public class NewsContentFragment extends Fragment {
    private View view;
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 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);
        newsTitleText.setText(newsTitle);// 刷新新闻标题
        newsContentText.setText(newsContent);// 刷新新闻内容

    }
}

refresh()用来显示新闻的标题和内容

此时,新闻内容的碎片和布局都创建好了,但是它们都是在双页模式中使用的,要在单页活动中使用,还得创建一个活动NewsContentActivity,并将布局指定成news_content,然后修改news_content.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:orientation="vertical"
    android:layout_height="match_parent"
    tools:context=".NewsContentActivity">
<fragment
    android:id="@+id/news_content_fragment"
    android:name="com.example.fragmentbestpractice.NewsContentFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
</LinearLayout>

这里直接在布局中引入NewsContentFragment相当于把news_content_frag布局的内容自动加了起来

然后修改NewsContentActivity中的代码,如下:

``

public class NewsContentActivity extends AppCompatActivity {
    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);
    }
    @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);
    }
}

在onCreate()方法中通过Intent获得传入的新闻标题和 新闻内容,然后调用FragmentManager的findFragmentById()方法得到了NewsContentFragment的实例,接着调用它的refresh()方法,并将新闻的标题和内容传入,就可以把这些数据显示出来了。

接下来再创建一个用于显示新闻列表的布局,熙年间news_title_frag.xml代码如下:

``

<?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:id="@+id/news_title_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

新建news_item.xml作为RecyclerView子项的布局,代码如下:

``

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/news_title"
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"
    android:singleLine="true"//表示让这个TextView单行显示
    android:ellipsize="end"//设定文本内容超出控件宽度时,文本的缩略方式,这里表示在尾部进行缩略
    android:textSize="18sp"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:paddingTop="15dp"
    android:paddingBottom="15dp"
    />

新建NewsTitleFragment作为展示新闻列表的碎片,代码如下:

``

public class NewsTitleFragment extends Fragment {
    private  boolean isTwoPane;
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        View view=inflater.inflate(R.layout.news_title_frag,container,false);
        return view;
    }
    public void onActivityCreated(Bundle savedInstanceState){
        super.onActivityCreated(savedInstanceState);
        if(getActivity().findViewById(R.id.news_content_layout)!=null){
            isTwoPane=true;
        }else isTwoPane=false;
    }
}

onActivityCreated()方法通过能否找到id为news_content_layout的View来判断wei当前是双页模式还是单页模式,因此我们需要将这个id为news_content_layout的View只在双页模式时出现,只要借助我们刚才学的限定符即可,首先修改 activity_main.xml中的代码如下:

``

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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/news_title_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <fragment
        android:id="@+id/news_title_fragment"
        android:name="com.example.fragmentbestpractice.NewsTitleFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</FrameLayout>

上述代码表示,单页模式只会加载一个新闻标题的碎片

新建layout-sw600dp文件夹,在这个下面再建立一个activity_main.xml文件,代码如下:

``

<?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:id="@+id/news_title_fragment"
        android:name="com.example.fragmentbestpractice.NewsTitleFragment"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent"/>
    <fragment
        android:id="@+id/news_content_layout"
        android:layout_width="0dp"
        android:layout_weight="3"
        android:layout_height="match_parent"/>
    <fragment
        android:id="@+id/news_content_fragment"
        android:name="com.example.fragmentbestpractice.NewsContentFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

双页模式中我们同时引入了两个碎片,并将新闻内容的碎片放在了一个FrameLayout布局下,而这个布局的id正式news_content_layout,因此能够找到这个id就是双页模式,不是就是单页模式

在NewsTitleFragment中通过RecyclerView将新闻列表展示出来,在NEwsTitkeFragment中新建一个内部类NewAdaptrt来作为RecyclerView的适配器,代码如下:

``

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.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;

import java.util.List;

public class NewsTitleFragment extends Fragment {
    private  boolean isTwoPane;
    class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.ViewHolder>{
        private List<News>mNewsList;

        @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 v) {
                    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();
        }

        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;
        }


    }

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        View view=inflater.inflate(R.layout.news_title_frag,container,false);
        return view;
    }
    public void onActivityCreated(Bundle savedInstanceState){
        super.onActivityCreated(savedInstanceState);
        if(getActivity().findViewById(R.id.news_content_layout)!=null){
            isTwoPane=true;
        }else isTwoPane=false;
    }
}

onCreateViewHolder()方法中注册的点击事件,首先获取了点击项的News实例,然后通过isTwoPane变量来判断当前是单页还是双页模式,单页就启动新活动曲线是新闻内容,双页就去更新新闻内容碎片的数据

最后向RecycleView填充数据,修改NewsTitleFragment代码,如下:

``

public class NewsTitleFragment extends Fragment {
    private  boolean isTwoPane;
    class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.ViewHolder>{
        private List<News>mNewsList;

        @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 v) {
                    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();
        }

        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;
        }


    }

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        View view=inflater.inflate(R.layout.news_title_frag,container,false);
        RecyclerView newsTitleRecycleView=(RecyclerView)view.findViewById(R.id.news_title_recycler_view);
        LinearLayoutManager layoutManager=new LinearLayoutManager(getActivity());
        newsTitleRecycleView.setLayoutManager(layoutManager);
        NewsAdapter adapter=new NewsAdapter(getNews());
        newsTitleRecycleView.setAdapter(adapter);
        return view;
    }

    private List<News> getNews() {
        List<News>newsList=new ArrayList<>();
        for(int i=1;i<50;i++){
            News news=new News();
            news.setTitle("This is news 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();
    }

    public void onActivityCreated(Bundle savedInstanceState){
        super.onActivityCreated(savedInstanceState);
        if(getActivity().findViewById(R.id.news_content_layout)!=null){
            isTwoPane=true;
        }else isTwoPane=false;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值