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代碼不用修改,運行項目

結果:

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM