我是跟着《Android第一行代码》写代码的,想写个博来加深印象一点
一、添加依赖库RecyclerView
在app下的build.gradle中的dependencies添加一句:(添加后要sync now)
implementation ‘androidx.recyclerview:recyclerview:1.0.0‘
二、新建一个新闻类News.java
1 public class News { 2 private String title;//新闻标题 3 private String content;//新闻内容 4 5 public String getTitle() { 6 return title; 7 } 8 9 public void setTitle(String title) { 10 this.title = title; 11 } 12 13 public String getContent() { 14 return content; 15 } 16 17 public void setContent(String content) { 18 this.content = content; 19 } 20 21 22 }
三、新建新闻内容的布局文件news_content_frag.xml
每条新闻内容的布局,头部显示新闻标题,正文部分显示新闻内容,中间用一条细线分隔开,其中,细线使用View实现。
1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent"> 5 6 <LinearLayout 7 android:id="@+id/visibility_layout" 8 android:layout_width="match_parent" 9 android:layout_height="match_parent" 10 android:orientation="vertical" 11 android:visibility="invisible"> 12 13 <TextView 14 android:id="@+id/news_title" 15 android:layout_width="match_parent" 16 android:layout_height="wrap_content" 17 android:gravity="center" 18 android:padding="10dp" 19 android:textSize="20sp"/> 20 <View 21 android:layout_width="match_parent" 22 android:layout_height="1dp" 23 android:background="#000"/> 24 <TextView 25 android:id="@+id/news_content" 26 android:layout_width="match_parent" 27 android:layout_height="0dp" 28 android:layout_weight="1" 29 android:padding="15dp" 30 android:textSize="18sp"/> 31 </LinearLayout> 32 <View 33 android:layout_width="match_parent" 34 android:layout_height="1dp" 35 android:layout_alignParentLeft="true" 36 android:background="#000"/> 37 38 </RelativeLayout>
四、新建NewContentFragment类(双页模式)
加载news_content_frag布局和将新闻的标题、内容显示在界面上。
1 package com.example.fragmentbestpractice; 2 3 import android.os.Bundle; 4 import android.view.LayoutInflater; 5 import android.view.View; 6 import android.view.ViewGroup; 7 import android.widget.TextView; 8 9 import androidx.annotation.NonNull; 10 import androidx.annotation.Nullable; 11 import androidx.appcompat.app.AppCompatActivity; 12 import androidx.fragment.app.Fragment; 13 14 public class NewsContentFragment extends Fragment { 15 private View view; 16 17 @Nullable 18 @Override//加载news_content_frag布局 19 public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 20 view=inflater.inflate(R.layout.news_content_frag,container,false); 21 return view; 22 } 23 public void refresh(String newsTitle,String newsContent){ 24 View visibilityLayout=view.findViewById(R.id.visibility_layout);//获取新闻布局 25 visibilityLayout.setVisibility(View.VISIBLE);//将新闻布局设置成可见 26 TextView newsTitleText=(TextView)view.findViewById(R.id.news_title);//获取新闻标题的控件 27 TextView newsContentText=(TextView)view.findViewById(R.id.news_content);//获取新闻内容的控件 28 newsTitleText.setText(newsTitle); //刷新新闻的标题 29 newsContentText.setText(newsContent);//刷新新闻的内容 30 } 31 }
五、单页模式
若想新闻内容能在单页模式下也能使用,还需要再创建一个活动NewsContentActivity,并将布局名指定成news_content.xml.
1.news_content.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent"> 6 <fragment 7 android:id="@+id/news_content_fragment" 8 android:name="com.example.fragmentbestpractice.NewsContentFragment" 9 android:layout_width="match_parent" 10 android:layout_height="match_parent"/> 11 </LinearLayout>
这里充分发挥了代码的复用性,android:name属性来显式指明要添加的碎片类名,直接在布局中引入了NewsContentFragment,相当于把news_content_frag布局的内容自动加了进来。
2.NewsContentActivity.java
1 package com.example.fragmentbestpractice; 2 3 import androidx.appcompat.app.AppCompatActivity; 4 5 import android.content.Context; 6 import android.content.Intent; 7 import android.os.Bundle; 8 9 public class NewsContentActivity extends AppCompatActivity { 10 public static void actionStart(Context context,String newsTitle,String newsContent){ 11 Intent intent=new Intent(context,NewsContentActivity.class); 12 intent.putExtra("news_title",newsTitle); 13 intent.putExtra("news_content",newsContent); 14 context.startActivity(intent); 15 } 16 @Override 17 protected void onCreate(Bundle savedInstanceState) { 18 super.onCreate(savedInstanceState); 19 setContentView(R.layout.news_content); 20 String newsTitle=getIntent().getStringExtra("news_title");//获取传入的新闻标题 21 String newsContent=getIntent().getStringExtra("news_content");//获取传入的新闻内容 22 NewsContentFragment newsContentFragment=(NewsContentFragment)getSupportFragmentManager() 23 .findFragmentById(R.id.news_content_fragment); 24 newsContentFragment.refresh(newsTitle,newsContent);//刷新NewsContentFragment界面 25 } 26 }
六、新建一个用于显示新闻标题列表的布局news_title_frag.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent"> 6 7 <androidx.recyclerview.widget.RecyclerView 8 android:id="@+id/news_title_recycler_view" 9 android:layout_width="match_parent" 10 android:layout_height="match_parent"/> 11 12 </LinearLayout>
RecyclerView子项的布局news_item.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <!--这是标题列表里的每个子项,即每个新闻标题--> 3 <TextView xmlns:android="http://schemas.android.com/apk/res/android" 4 android:id="@+id/news_title" 5 android:layout_width="match_parent" 6 android:layout_height="wrap_content" 7 android:maxLines="1" 8 android:ellipsize="end" 9 android:textSize="18sp" 10 android:paddingLeft="10dp" 11 android:paddingRight="10dp" 12 android:paddingTop="15dp" 13 android:paddingBottom="15dp"> 14 15 </TextView>
七、展示新闻标题列表
NewsTitleFragment.java
1 package com.example.fragmentbestpractice; 2 3 import android.os.Bundle; 4 import android.view.LayoutInflater; 5 import android.view.View; 6 import android.view.ViewGroup; 7 import android.widget.TextView; 8 9 import androidx.annotation.NonNull; 10 import androidx.annotation.Nullable; 11 import androidx.fragment.app.Fragment; 12 import androidx.recyclerview.widget.LinearLayoutManager; 13 import androidx.recyclerview.widget.RecyclerView; 14 15 import java.util.ArrayList; 16 import java.util.List; 17 import java.util.Random; 18 19 /** 20 * 展示新闻列表 21 */ 22 public class NewsTitleFragment extends Fragment { 23 private boolean isTwopane;//判断是否显示双页 24 25 @Nullable 26 @Override 27 public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 28 View view=inflater.inflate(R.layout.news_title_frag,container,false); 34 return view; 35 } 57 @Override 58 public void onActivityCreated(@Nullable Bundle savedInstanceState) { 59 super.onActivityCreated(savedInstanceState); 60 if(getActivity().findViewById(R.id.news_content_layout)!=null){ 61 isTwopane=true;//可以找到news_content_layout布局时,为双页模式 62 }else{ 63 isTwopane=false;//找不到news_content_layout布局时,为单页模式 64 } 65 } 109 } 110 }
修改activity_main.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <!--在单页模式下,只显示一个新闻标题碎片--> 3 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 4 android:id="@+id/activity_main" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 > 8 9 <fragment 10 android:id="@+id/news_title_fragment" 11 android:name="com.example.fragmentbestpractice.NewsTitleFragment" 12 android:layout_width="match_parent" 13 android:layout_height="match_parent"/> 14 15 </FrameLayout>
上述代码表示,在单页模式下,只会加载一个新闻标题的碎片
新建一个layout-sw600dp文件夹,在该文件夹下新建一个文件,命名为“activity_main.xml”,然后修改里面的代码
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:orientation="horizontal" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent"> 5 6 <fragment 7 android:id="@+id/news_title_fragment" 8 android:name="com.example.fragmentbestpractice.NewsTitleFragment" 9 android:layout_width="0dp" 10 android:layout_height="match_parent" 11 android:layout_weight="1"/> 12 <FrameLayout 13 android:id="@+id/news_content_layout" 14 android:layout_width="0dp" 15 android:layout_height="match_parent" 16 android:layout_weight="3"> 17 <fragment 18 android:id="@+id/news_content_fragment" 19 android:name="com.example.fragmentbestpractice.NewsContentFragment" 20 android:layout_width="match_parent" 21 android:layout_height="match_parent"/> 22 23 </FrameLayout> 24 25 26 </LinearLayout>
八、在NewsTitleFragment中通过RecyclerView将新闻列表展示出来,在NewsTitleFragment新建一个内部类NewsAdapter来作为RecyclerView的适配器
NewsTitleFragment.java
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;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; } private List<News> getNews() { List<News> newsList=new ArrayList<>(); for(int i=0;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(); } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); if(getActivity().findViewById(R.id.news_content_layout)!=null){ isTwopane=true;//可以找到news_content_layout布局时,为双页模式 }else{ isTwopane=false;//找不到news_content_layout布局时,为单页模式 } } class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.ViewHolder>{ private List<News> mNewsList; class ViewHolder extends RecyclerView.ViewHolder{ TextView newsTitleText; //构造器传入一个View参数,View参数就是RecyclerView子项的最外层布局 public ViewHolder(View view){ super(view); newsTitleText=(TextView)view.findViewById(R.id.news_title); } } //NewsAdapter内部类的构造器,这个方法用于将要展示在界面的数据源传进来,并赋值给一个全局变量mFruitAdapter public NewsAdapter(List<News> newsList){ mNewsList=newsList; } @NonNull @Override //因为NewsAdapter是继承RecyclerView.Adapeter的,所以必须重写以下三个方法 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);//将加载的布局传入到ViewHolder类构造函数中 view.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v) {//当用户点击每一个新闻标题时,就会显示新闻内容 News news=mNewsList.get(holder.getAdapterPosition()); if(isTwopane){//如果是双页模式,则刷新NewsContentFragment的内容 NewsContentFragment newsContentFragment=(NewsContentFragment)getFragmentManager().findFragmentById(R.id.news_content_fragment); newsContentFragment.refresh(news.getTitle(),news.getContent()); }else{//如果是单页模式,直接启动NewsContentActivity NewsContentActivity.actionStart(getActivity(),news.getTitle(),news.getContent()); } } }); return holder; } @Override //该方法用于对RecyclerView子项的数据进行赋值,会在每个子项被滚动到屏幕内的时候执行 public void onBindViewHolder(@NonNull ViewHolder holder, int position) { News news=mNewsList.get(position);//通过position得到当前项的News实例 holder.newsTitleText.setText(news.getTitle());//在将数据设置到ViewHolder的newsTitleText } @Override //返回数据源长度 public int getItemCount() { return mNewsList.size(); } }}
九、MainActivity.java代码不用修改,运行项目
结果:
原文地址:https://www.cnblogs.com/panqiaoyan/p/12654748.html