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

Posted 要加油

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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代码不用修改,运行项目

结果:

 

 

 

以上是关于Android第一行代码之制作简易版新闻应用的主要内容,如果未能解决你的问题,请参考以下文章

简易版的新闻应用

第一行代码——Android高清版pdf免费下载

第一行代码 Android 第三版读后感

android之简易新闻客户端

Fragment实践————简易版新闻应用

Android Studio学习第一篇制作一个拥有登录和注册功能的简易APP