📜  如何在 Android 中创建新闻应用程序?

📅  最后修改于: 2022-05-13 01:55:24.583000             🧑  作者: Mango

如何在 Android 中创建新闻应用程序?

网络是 android 开发不可或缺的一部分,尤其是在构建数据驱动的客户端时。主要用于网络连接的Java类是HttpUrlConnection。该类需要手动管理数据解析和请求的异步执行。对于网络操作,我们最好使用一个名为 Fast Android Networking Library 的库,它可以负责发送和解析网络请求。在本文中,我们将逐步介绍构建 android 新闻应用程序的过程。 Fast Android Networking Library 支持所有类型的 HTTP/HTTPS 请求,在我们的应用程序中,我们将使用它

  • 执行 GET 请求
  • 将来自 Internet 的图像加载到 ImageViews 中

这是应用程序最终的样子:

输出 GIF

分步实施

第 1 步:创建一个新项目

要了解如何在 Android Studio 中创建新项目,请参阅如何在 Android Studio 中创建/启动新项目并选择Java作为编程语言。

第二步:添加依赖

选择Gradle Scripts > build.gradle(Module:app)并在依赖项部分添加以下依赖项。

implementation 'com.amitshekhar.android:android-networking:1.0.2'
implementation 'com.amitshekhar.android:jackson-android-networking:1.0.2'

添加依赖项后,通过单击立即同步来同步您的项目。

第三步:添加权限

选择manifests > AndroidManifest.xml并在应用标签上方添加互联网权限。

    

第 4 步:获取 API 密钥

访问 newsapi 并注册。该密钥将在注册后显示并发送到您的电子邮件收件箱。

第 5 步:创建一个新的空 Activity 并将 WebView 添加到布局中

转到app > Java > 右键单击 > New > Activity > Empty Activity并将其命名为 WebActivity。此活动将显示文章的网页作为活动布局的一部分。将 WebView 添加到activity_web.xml文件。导航到app > res > layout > activity_web.xml并将以下代码添加到该文件。

XML


  
    
    
  


Java
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.webkit.WebView;
  
public class WebActivity extends AppCompatActivity {
    // setting the TAG for debugging purposes
    private static String TAG="WebActivity";
  
    // declaring the webview
    private WebView myWebView;
  
    // declaring the url string variable
    private String url;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web);
  
        // assigning the views to id's
        myWebView = (WebView) findViewById(R.id.webview);
  
        Intent intent = getIntent();
  
        // checking if there is an intent
        if(intent!=null){
            // retrieving the url in the intent
            url = intent.getStringExtra("url_key");
  
            // loading and displaying a
            // web page in the activity
            myWebView.loadUrl(url);
        }
  
    }
  
    @Override
    protected void onRestart() {
        super.onRestart();
        finish();
    }
}


XML


  
    
    
    
  
    
    
    
  


XML


  
    
    
  
        
        
        
  
        
  
            
            
  
            
            
  
        
  
    
  
    
    
  
    
    
  


Java
public class NewsArticle {
    
    // the properties/attributes
    // of the ArticleModel
    String author;
    String title;
    String description;
    String url;
    String urlToImage;
    String publishedAt;
    String content;
  
    // ArticleModel empty constructor
    public NewsArticle() {
    }
  
    // get method : returns the name of the author
    public String getAuthor() {
        return author;
    }
  
    // set method : sets the author
    public void setAuthor(String author) {
        this.author = author;
    }
  
    // get method : returns the title of the article
    public String getTitle() {
        return title;
    }
  
    // set method : sets the title
    public void setTitle(String title) {
        this.title = title;
    }
  
    // get method : returns the description of the article
    public String getDescription() {
        return description;
    }
  
    // set method : sets the description
    public void setDescription(String description) {
        this.description = description;
    }
  
    // get method : returns url of the article
    public String getUrl() {
        return url;
    }
  
    // set method : sets the url of the article
    public void setUrl(String url) {
        this.url = url;
    }
  
    // get method : returns the urlToImage of the article
    public String getUrlToImage() {
        return urlToImage;
    }
  
    // set method : sets the UrlToImage
    public void setUrlToImage(String urlToImage) {
        this.urlToImage = urlToImage;
    }
  
    // get method : returns the date
    public String getPublishedAt() {
        return publishedAt;
    }
  
    // set method : sets the date
    public void setPublishedAt(String publishedAt) {
        this.publishedAt = publishedAt;
    }
  
    // get method : returns the content of the article
    public String getContent() {
        return content;
    }
  
    // set method : sets the title
    public void setContent(String content) {
        this.content = content;
    }
}


Java
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.androidnetworking.widget.ANImageView;
import java.util.ArrayList;
  
public class ArticleAdapter extends RecyclerView.Adapter {
    // setting the TAG for debugging purposes
    private static String TAG="ArticleAdapter";
  
    private ArrayList mArrayList;
    private Context mContext;
  
    public ArticleAdapter(Context context,ArrayList list){
        // initializing the constructor
        this.mContext=context;
        this.mArrayList=list;
    }
  
    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        // inflating the layout with the article view  (R.layout.article_item)
        View view=LayoutInflater.from(mContext).inflate(R.layout.article_item,parent,false);
        return new ViewHolder(view);
    }
  
    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        // the parameter position is the index of the current article
        // getting the current article from the ArrayList using the position
        NewsArticle currentArticle=mArrayList.get(position);
  
        // setting the text of textViews
        holder.title.setText(currentArticle.getTitle());
        holder.description.setText(currentArticle.getDescription());
  
        // subString(0,10) trims the date to make it short
        holder.contributordate.setText(currentArticle.getAuthor()+
                " | "+currentArticle.getPublishedAt().substring(0,10));
  
        // Loading image from network into  
        // Fast Android Networking View ANImageView
        holder.image.setDefaultImageResId(R.drawable.ic_launcher_background);
        holder.image.setErrorImageResId(R.drawable.ic_launcher_foreground);
        holder.image.setImageUrl(currentArticle.getUrlToImage());
  
        // setting the content Description on the Image
        holder.image.setContentDescription(currentArticle.getContent());
  
        // handling click event of the article
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // an intent to the WebActivity that display web pages
                Intent intent = new Intent(mContext, WebActivity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.putExtra("url_key",currentArticle.getUrl());
  
                // starting an Activity to display the page of the article
                mContext.startActivity(intent);
            }
        });
  
    }
  
    @Override
    public int getItemCount() {
        return mArrayList.size();
    }
  
    public class ViewHolder extends RecyclerView.ViewHolder{
  
        // declaring the views
        private TextView title,description,contributordate;
        private ANImageView image;
  
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            // assigning views to their ids
            title=itemView.findViewById(R.id.title_id);
            description=itemView.findViewById(R.id.description_id);
            image=itemView.findViewById(R.id.image_id);
            contributordate=itemView.findViewById(R.id.contributordate_id);
        }
    }
  
}


Java
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import com.androidnetworking.AndroidNetworking;
import com.androidnetworking.common.Priority;
import com.androidnetworking.error.ANError;
import com.androidnetworking.interfaces.JSONObjectRequestListener;
import com.jacksonandroidnetworking.JacksonParserFactory;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
  
import java.util.ArrayList;
  
public class MainActivity extends AppCompatActivity {
     
    // TODO : set the API_KEY variable to your api key
    private static  String API_KEY="";
  
    // setting the TAG for debugging purposes
    private static String TAG="MainActivity";
  
    // declaring the views
    private ProgressBar mProgressBar;
    private RecyclerView mRecyclerView;
  
    // declaring an ArrayList of articles
    private ArrayList mArticleList;
  
    private ArticleAdapter mArticleAdapter;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
  
        // initializing the Fast Android Networking Library
        AndroidNetworking.initialize(getApplicationContext());
  
        // setting the JacksonParserFactory
        AndroidNetworking.setParserFactory(new JacksonParserFactory());
  
        // assigning views to their ids
        mProgressBar=(ProgressBar)findViewById(R.id.progressbar_id);
        mRecyclerView=(RecyclerView)findViewById(R.id.recyclerview_id);
  
        // setting the recyclerview layout manager
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
  
        // initializing the ArrayList of articles
        mArticleList=new ArrayList<>();
  
        // calling get_news_from_api()
        get_news_from_api();
    }
  
    public void get_news_from_api(){
        // clearing the articles list before adding news ones
        mArticleList.clear();
  
        // Making a GET Request using Fast
        // Android Networking Library
        // the request returns a JSONObject containing 
        // news articles from the news api
        // or it will return an error
        AndroidNetworking.get("https://newsapi.org/v2/top-headlines")
                .addQueryParameter("country", "in")
                .addQueryParameter("apiKey",API_KEY)
                .addHeaders("token", "1234")
                .setTag("test")
                .setPriority(Priority.LOW)
                .build()
                .getAsJSONObject(new JSONObjectRequestListener(){
                    @Override
                    public void onResponse(JSONObject response) {
                        // disabling the progress bar
                        mProgressBar.setVisibility(View.GONE);
  
                        // handling the response
                        try {
  
                            // storing the response in a JSONArray
                            JSONArray articles=response.getJSONArray("articles");
  
                            // looping through all the articles
                            // to access them individually
                            for (int j=0;j


第 6 步:使用 WebActivity。Java

下面是WebActivity 的代码。Java

Java

import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.webkit.WebView;
  
public class WebActivity extends AppCompatActivity {
    // setting the TAG for debugging purposes
    private static String TAG="WebActivity";
  
    // declaring the webview
    private WebView myWebView;
  
    // declaring the url string variable
    private String url;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web);
  
        // assigning the views to id's
        myWebView = (WebView) findViewById(R.id.webview);
  
        Intent intent = getIntent();
  
        // checking if there is an intent
        if(intent!=null){
            // retrieving the url in the intent
            url = intent.getStringExtra("url_key");
  
            // loading and displaying a
            // web page in the activity
            myWebView.loadUrl(url);
        }
  
    }
  
    @Override
    protected void onRestart() {
        super.onRestart();
        finish();
    }
}

第 7 步:将 RecyclerView 添加到 activity_main.xml 文件

选择app > res > layout > activity_main.xml并将以下代码添加到该文件。 RecyclerView 用于有效地显示数据列表,在我们的例子中,它将显示新闻文章列表。

XML



  
    
    
    
  
    
    
    
  

第 8 步:创建新的自定义布局

导航到文件 > 新建 > XML > 布局 XML 文件并将其命名为 article_item。 article_item.xml文件将用于新闻文章列表中的每一行。下面是article_item.xml文件的代码。

XML



  
    
    
  
        
        
        
  
        
  
            
            
  
            
            
  
        
  
    
  
    
    
  
    
    
  

第 9 步:创建 NewsArticle 模型类

导航到应用程序 > Java > 包 > 右键单击包 > 新建 > Java类并将其命名为 NewsArticle。我们创建了这个模型类来存储新闻文章数据,如标题、内容、描述等

在我们的模型类中,主要有三种方法:

  • 构造函数:初始化新创建的 NewsArticle 对象
  • 获取方法:用于获取属性值
  • 设置方法:用于设置属性值

下面是NewsArticle 的代码。 Java文件。

Java

public class NewsArticle {
    
    // the properties/attributes
    // of the ArticleModel
    String author;
    String title;
    String description;
    String url;
    String urlToImage;
    String publishedAt;
    String content;
  
    // ArticleModel empty constructor
    public NewsArticle() {
    }
  
    // get method : returns the name of the author
    public String getAuthor() {
        return author;
    }
  
    // set method : sets the author
    public void setAuthor(String author) {
        this.author = author;
    }
  
    // get method : returns the title of the article
    public String getTitle() {
        return title;
    }
  
    // set method : sets the title
    public void setTitle(String title) {
        this.title = title;
    }
  
    // get method : returns the description of the article
    public String getDescription() {
        return description;
    }
  
    // set method : sets the description
    public void setDescription(String description) {
        this.description = description;
    }
  
    // get method : returns url of the article
    public String getUrl() {
        return url;
    }
  
    // set method : sets the url of the article
    public void setUrl(String url) {
        this.url = url;
    }
  
    // get method : returns the urlToImage of the article
    public String getUrlToImage() {
        return urlToImage;
    }
  
    // set method : sets the UrlToImage
    public void setUrlToImage(String urlToImage) {
        this.urlToImage = urlToImage;
    }
  
    // get method : returns the date
    public String getPublishedAt() {
        return publishedAt;
    }
  
    // set method : sets the date
    public void setPublishedAt(String publishedAt) {
        this.publishedAt = publishedAt;
    }
  
    // get method : returns the content of the article
    public String getContent() {
        return content;
    }
  
    // set method : sets the title
    public void setContent(String content) {
        this.content = content;
    }
}

第 10 步:创建一个 ArticleAdapter 类

导航到app > Java > package > 右键单击 package > New > Java Class并将其命名为 ArticleAdapter。 ArticleAdapter 类负责从 NewsArticle 模型中获取数据并将其显示在视图上。适配器将提供对数据项的访问,并负责为数据集中的每篇新闻文章创建一个视图。下面是ArticleAdapter 的代码。 Java文件。

Java

import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.androidnetworking.widget.ANImageView;
import java.util.ArrayList;
  
public class ArticleAdapter extends RecyclerView.Adapter {
    // setting the TAG for debugging purposes
    private static String TAG="ArticleAdapter";
  
    private ArrayList mArrayList;
    private Context mContext;
  
    public ArticleAdapter(Context context,ArrayList list){
        // initializing the constructor
        this.mContext=context;
        this.mArrayList=list;
    }
  
    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        // inflating the layout with the article view  (R.layout.article_item)
        View view=LayoutInflater.from(mContext).inflate(R.layout.article_item,parent,false);
        return new ViewHolder(view);
    }
  
    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        // the parameter position is the index of the current article
        // getting the current article from the ArrayList using the position
        NewsArticle currentArticle=mArrayList.get(position);
  
        // setting the text of textViews
        holder.title.setText(currentArticle.getTitle());
        holder.description.setText(currentArticle.getDescription());
  
        // subString(0,10) trims the date to make it short
        holder.contributordate.setText(currentArticle.getAuthor()+
                " | "+currentArticle.getPublishedAt().substring(0,10));
  
        // Loading image from network into  
        // Fast Android Networking View ANImageView
        holder.image.setDefaultImageResId(R.drawable.ic_launcher_background);
        holder.image.setErrorImageResId(R.drawable.ic_launcher_foreground);
        holder.image.setImageUrl(currentArticle.getUrlToImage());
  
        // setting the content Description on the Image
        holder.image.setContentDescription(currentArticle.getContent());
  
        // handling click event of the article
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // an intent to the WebActivity that display web pages
                Intent intent = new Intent(mContext, WebActivity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.putExtra("url_key",currentArticle.getUrl());
  
                // starting an Activity to display the page of the article
                mContext.startActivity(intent);
            }
        });
  
    }
  
    @Override
    public int getItemCount() {
        return mArrayList.size();
    }
  
    public class ViewHolder extends RecyclerView.ViewHolder{
  
        // declaring the views
        private TextView title,description,contributordate;
        private ANImageView image;
  
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            // assigning views to their ids
            title=itemView.findViewById(R.id.title_id);
            description=itemView.findViewById(R.id.description_id);
            image=itemView.findViewById(R.id.image_id);
            contributordate=itemView.findViewById(R.id.contributordate_id);
        }
    }
  
}

第 11 步:使用 MainActivity。Java

在我们的活动中,我们将使用 Android 快速库向新闻 API 发出 GET 请求,并使用新闻文章填充 RecyclerView。首先,我们将创建一个字符串变量并将其设置为 API 密钥(我们在步骤 4 中创建的密钥)。例如,如果您的 API 密钥 = b971358de21d4af48ae24b5faf06bbok。然后将变量声明为:

private static  String API_KEY="b971358de21d4af48ae24b5faf06bbok";

下面是MainActivity 的代码。 Java文件。

Java

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import com.androidnetworking.AndroidNetworking;
import com.androidnetworking.common.Priority;
import com.androidnetworking.error.ANError;
import com.androidnetworking.interfaces.JSONObjectRequestListener;
import com.jacksonandroidnetworking.JacksonParserFactory;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
  
import java.util.ArrayList;
  
public class MainActivity extends AppCompatActivity {
     
    // TODO : set the API_KEY variable to your api key
    private static  String API_KEY="";
  
    // setting the TAG for debugging purposes
    private static String TAG="MainActivity";
  
    // declaring the views
    private ProgressBar mProgressBar;
    private RecyclerView mRecyclerView;
  
    // declaring an ArrayList of articles
    private ArrayList mArticleList;
  
    private ArticleAdapter mArticleAdapter;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
  
        // initializing the Fast Android Networking Library
        AndroidNetworking.initialize(getApplicationContext());
  
        // setting the JacksonParserFactory
        AndroidNetworking.setParserFactory(new JacksonParserFactory());
  
        // assigning views to their ids
        mProgressBar=(ProgressBar)findViewById(R.id.progressbar_id);
        mRecyclerView=(RecyclerView)findViewById(R.id.recyclerview_id);
  
        // setting the recyclerview layout manager
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
  
        // initializing the ArrayList of articles
        mArticleList=new ArrayList<>();
  
        // calling get_news_from_api()
        get_news_from_api();
    }
  
    public void get_news_from_api(){
        // clearing the articles list before adding news ones
        mArticleList.clear();
  
        // Making a GET Request using Fast
        // Android Networking Library
        // the request returns a JSONObject containing 
        // news articles from the news api
        // or it will return an error
        AndroidNetworking.get("https://newsapi.org/v2/top-headlines")
                .addQueryParameter("country", "in")
                .addQueryParameter("apiKey",API_KEY)
                .addHeaders("token", "1234")
                .setTag("test")
                .setPriority(Priority.LOW)
                .build()
                .getAsJSONObject(new JSONObjectRequestListener(){
                    @Override
                    public void onResponse(JSONObject response) {
                        // disabling the progress bar
                        mProgressBar.setVisibility(View.GONE);
  
                        // handling the response
                        try {
  
                            // storing the response in a JSONArray
                            JSONArray articles=response.getJSONArray("articles");
  
                            // looping through all the articles
                            // to access them individually
                            for (int j=0;j

输出: