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第一行代码之制作简易版新闻应用的主要内容,如果未能解决你的问题,请参考以下文章