• Android第一行代码之制作简易版新闻应用


    我是跟着《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代码不用修改,运行项目

    结果:

     

  • 相关阅读:
    01-Git 及其可视化工具TortoiseGit 的安装和使用
    IntelliJ IDEA中Warning:java:源值1.5已过时, 将在未来所有发行版中删除
    JVM学习笔记四_垃圾收集器与内存分配策略
    JVM学习笔记三_异常初步
    CentOs7 图形界面和命令行界面切换
    基本概念一
    JVM学习笔记二_对象的创建、布局和定位
    JVM学习笔记一_运行时数据区域
    个人阅读作业二
    软件工程随笔
  • 原文地址:https://www.cnblogs.com/panqiaoyan/p/12654748.html
Copyright © 2020-2023  润新知