Android Studio RecyclerView JSON API

 Android Studio RecyclerView JSON API

AndroidManifest權限設定

在AndroidManifest中加入網路訪問權限>

<uses-permission android :name ="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

Layout

activity_main

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerlist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:listitem="@layout/item_layout"/>

</LinearLayout>

item_layout

在Layout內新增Layout Resource File

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:background="@color/white">

<ImageView
android:id="@+id/coverImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="3dp"
android:scaleType="fitXY"/>

<TextView
android:id="@+id/img_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textColor="@color/red"/>

</RelativeLayout>

activity_article

new  Activity -> 命名 ArticleActivity

並在其Layout編寫
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ArticleActivity">

<TextView
android:id="@+id/date"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_gravity="center"
android:gravity="center"
android:text="2020 Dec. 17"
android:textSize="30dp" />

<ImageView
android:id="@+id/cover"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3"
android:scaleType="fitXY"
android:background="@drawable/ic_launcher_background"/>

<TextView
android:id="@+id/tit"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.5"
android:gravity="center"
android:text="Title"
android:textSize="14dp"/>

<TextView
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="4"
android:singleLine="false"
android:scrollbars="vertical"
android:maxLines = "20"
android:text="description"
android:textSize="18dp"/>

<TextView
android:id="@+id/copyright"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.5"
android:gravity="center"
android:text="Copyright"
android:textSize="14dp"/>

</LinearLayout>

Java

MainActivity

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import org.json.JSONArray;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

public static RecyclerView recyclerlist;
private static String JSON_URL = "https://raw.githubusercontent.com/cmmobile/NasaDataSet/main/apod.json";
public static List<Main_Data> DataList = new ArrayList<>();
private AsyncTask mTask;
private Main_Adapter adapter;
private Context mcontext;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewinit();
mTask = new Task().execute(JSON_URL);
}

@Override
protected void onDestroy() {
super.onDestroy();
if(mTask != null)
{
mTask.cancel(true);
}

}

private void viewinit()
{
mcontext = getApplicationContext();
recyclerlist = (RecyclerView) findViewById(R.id.recyclerlist);
}


private class Task extends AsyncTask<String, Integer, String> {
/**
* Params: 這個泛型指定的是我們傳遞給異步任務執行時的參數的類型
* Progress: 這個泛型指定的是我們的異步任務在執行的時候將執行的進度返回給UI線程的參數的類型
* Result: 這個泛型指定的異步任務執行完後返回給UI線程的結果的類型
*/
private ProgressDialog PD;
protected void onPreExecute() {
//執行前 設定可以在這邊設定
super.onPreExecute();
PD = new ProgressDialog(MainActivity.this);
PD.setMessage("Please wait...");
PD.setIndeterminate(false);
PD.setMax(100);
PD.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
PD.setCancelable(false);
PD.show();

GridLayoutManager layoutManager = new GridLayoutManager(mcontext, 4);
recyclerlist.setLayoutManager(layoutManager);
}

@Override
protected String doInBackground(String... params) {
//執行中 在背景做事情
try
{
URL murl = new URL(JSON_URL);
//得到網路訪問物件java.net.HttpURLConnection
HttpURLConnection connection = (HttpURLConnection) murl.openConnection();
//從流中讀取響應資訊將位元組流轉換為字元流,修改字符集編碼
InputStream is = connection.getInputStream();
//字元輸入流中讀取文字,緩衝各個字元
BufferedReader in = new BufferedReader(new InputStreamReader(is));
StringBuffer json = new StringBuffer();
                String line = in.readLine();
while (line != null ) {
json.append(line);
line = in.readLine();
}

JSONArray jsonArray = new JSONArray(String.valueOf(json));
for (int i = 0; i < jsonArray.length(); i++) {
publishProgress(((i * 100) / jsonArray.length()));
JSONObject jsonObject = jsonArray.getJSONObject(i);
String description = jsonObject.getString("description");
String copyright = jsonObject.getString("copyright");
                    String title = jsonObject.getString("title");
String img_url = jsonObject.getString("url");
String date = jsonObject.getString("date");
String hdurl = jsonObject.getString("hdurl");
DataList.add(new Main_Data(description, copyright, title, img_url, date, hdurl));
}
}
catch (Exception e)
{
Log.d("JSONDown","=="+e.getMessage());
}
return null;
}

@Override
protected void onProgressUpdate(Integer... values) {
//執行中 可以在這邊告知使用者進度
PD.setProgress(values[0]);
super.onProgressUpdate(values);
}

@Override
protected void onPostExecute(String json) {
//執行後 完成背景任務
super.onPostExecute(json);
PD.dismiss();
adapter = new Main_Adapter(getApplicationContext(),DataList);
recyclerlist.setAdapter(adapter);
RecycleItemListener();
}

}

private void RecycleItemListener()
{
adapter.setOnItemClickListener(new Main_Adapter.OnItemClickListener()
{
@Override
public void onItemClick(RecyclerView parent, View view, int position, String data) {
Intent intent = new Intent();
intent.setClass(MainActivity.this,ArticleActivity.class);//更換Activity
Bundle bundle = new Bundle();
bundle.putString("title",DataList.get(position).getTitle());//傳遞資料到別的Activity 第一個為參數key,第二個為Value
bundle.putString("copyright",DataList.get(position).getcopyright());
bundle.putString("description",DataList.get(position).getdescription());
bundle.putString("date",DataList.get(position).getdate());
bundle.putString("hdurl",DataList.get(position).gethdurl());
intent.putExtras(bundle);
startActivity(intent);
// MainActivity.this.finish();
}
});
}
}

Adapter

import static com.cylemon.recycler_json_api.MainActivity.DataList;
import static com.cylemon.recycler_json_api.MainActivity.recyclerlist;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.List;

public class Main_Adapter extends RecyclerView.Adapter<Main_Adapter.ViewHolder> implements View.OnClickListener{

LayoutInflater inflater;

public Main_Adapter(Context ctx, List<Main_Data> Data)
{
this.inflater = LayoutInflater.from(ctx);
DataList = Data;
}
static class ViewHolder extends RecyclerView.ViewHolder{

TextView dataTitle;
ImageView dataCoverImage;

public ViewHolder(@NonNull View itemView) {
super(itemView);
dataTitle = itemView.findViewById(R.id.img_title);
dataCoverImage = itemView.findViewById(R.id.coverImage);
}
}

@NonNull
    @Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.item_layout,parent,false);
ViewHolder holder = new ViewHolder(view);
view.setOnClickListener(this);//建立View點擊監聽
return holder;
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Main_Data mdata = DataList.get(position);
holder.dataTitle.setText(mdata.getTitle());

//載入圖片
Thread mThread =new Thread(new Runnable () {
public void run() {
try {
URL url = new URL(mdata.getimg_url());
InputStream is = new BufferedInputStream(url.openStream());
Bitmap b = BitmapFactory.decodeStream(is);
holder.dataCoverImage.setImageBitmap(b);
} catch (Exception e) {
Log.d("IMGException","=="+e.getMessage());
}
}
});
        mThread. start(); }

@Override
public int getItemCount() {
return DataList.size();
}

private OnItemClickListener mOnItemClickListener = null;

public void setOnItemClickListener(OnItemClickListener onItemClickListener){
this.mOnItemClickListener = onItemClickListener;
}

public void onClick(View view) {
//根據RecyclerView獲得當前View的位置
int position = recyclerlist.getChildAdapterPosition(view);
//程式執行到此,會去執行具體實現的onItemClick()方法
if (mOnItemClickListener!=null){
mOnItemClickListener.onItemClick(recyclerlist,view,position, String.valueOf(DataList.get(position)));
}
}
public interface OnItemClickListener{
//引數(父元件,當前單擊的View,單擊的View的位置,資料)
        void onItemClick(RecyclerView parent, View view, int position, String data);
}

}

Data

public class Main_Data {

private String description;
private String copyright;
private String title;
private String img_url;
private String date;
private String hdurl;

public Main_Data(String description, String copyright, String title, String img_url, String date, String hdurl){
this.description = description;
this.copyright = copyright;
this.title = title;
this.img_url = img_url;
this.date = date;
this.hdurl = hdurl;
}

public String getdescription() {
return description;
}
public String getcopyright() {
return copyright;
}
public String getTitle() {
return title;
}
public String getimg_url() {
return img_url;
}
public String getdate() {
return date;
}
public String gethdurl() {
return hdurl;
}
}

結果

GitHub

Example提供參考

留言