大家好,请帮我从头到尾使用改造从回收器 View 中的嵌套 JSON 数组中获取数据,谢谢
最佳答案
See Overview Of All activity or class or interfaces whichever we need to make & same we will make it below
Here we hide some API data for security purpose & u can remove some Common class data as we set static sound method in it so
we have to set as a Main Image Item or Sub Image Item as per API
API -> https://________.in/childrenart/kidsgames.json
Here We have JSON Format like below - Nested Array
[
{
"id": 1,
"profile_image": "https://________.in/childrenart/profileimages/kg_maze_games.png",
"category_name": "kg_maze_games",
"category_images": [
{
"id": 1,
"image_url": "https://________.in/childrenart/category_images/kg_maze_games/kg_maze_games_01.png"
},
{
"id": 2,
"image_url": "https://________.in/childrenart/category_images/kg_maze_games/kg_maze_games_02.png"
}
]
},
{
"id": 2,
"profile_image": "https://________.in/childrenart/profileimages/kg_match_count.png",
"category_name": "kg_match_count",
"category_images": [
{
"id": 1,
"image_url": "https://________.in/childrenart/category_images/kg_match_count/kg_match_count_01.png"
},
{
"id": 2,
"image_url": "https://________.in/childrenart/category_images/kg_match_count/kg_match_count_02.png"
}
]
}
]
https://www.jsonschema2pojo.org/
Convert this JSON to POJO You will get 2 Ready Model Class
Dont forget to Set Source type: as a JSON & Annotation style: Gson in the below link
Paste your JSON Data & Get model class as a Zip or copy from Preview
https://www.jsonschema2pojo.org/
Now Create new Project in java & Add below Depndencies
in -> build.gradle(Module)
// gson Retrofit
implementation 'com.google.code.gson:gson:2.8.7'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.2.1'
// glide
implementation 'com.github.bumptech.glide:glide:4.13.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.13.0'
in -> Gradle.properties
android.nonTransitiveRClass=true
android.enableJetifier=true
Now Lest start to make classes , interfaces , activities as below 14 step wise
To Get Main Iamge From API (profile_image)
Step Type - Name
(01) Model Class - Main Image Item
(02) Model Class - Sub Image Item
(03) Interface(Api) - KidsGameApiCall
(04) Activity(Main) - KidsGameActivity
(05) Activity(MainXML-Layout) - activity_kids_game
(06) Class - Common
(07) Custom Layout - item_main_image
(08) Adapter - KidsGameAdapter
(09) Interface - KidsGamesItemClick
To Get Sub Iamge From Same API (category_name)
Type - Name
(10) Activity(Main) - KidsGameListActivity
(11) Activity(MainXML-Layout) - activity_kids_game_list
(12) Custom Layout - item_sub_image
(13) Adapter - KidsGameListAdapter
(14) Interface - KidsGamesListItemClick
(01) 模型类 - 主图像项
package com.example.childrenartsdrawing.models;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
public class MainImageItem {
@SerializedName("id")
@Expose
private Integer id;
@SerializedName("profile_image")
@Expose
private String profileImage;
@SerializedName("category_name")
@Expose
private String categoryName;
@SerializedName("category_images")
@Expose
private ArrayList<SubImageItem> categoryImages = null;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getProfileImage() {
return profileImage;
}
public void setProfileImage(String profileImage) {
this.profileImage = profileImage;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public ArrayList<SubImageItem> getCategoryImages() {
return categoryImages;
}
public void setCategoryImages(ArrayList<SubImageItem> categoryImages) {
this.categoryImages = categoryImages;
}
}
(02) 模型类 - 子图像项
package com.example.childrenartsdrawing.models;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class SubImageItem {
@SerializedName("id")
@Expose
private Integer id;
@SerializedName("image_url")
@Expose
private String imageUrl;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
}
(03) 接口(interface)(Api) - KidsGameApiCall
package com.example.childrenartsdrawing.interfaces;
import com.example.childrenartsdrawing.models.MainImageItem;
import java.util.ArrayList;
import retrofit2.Call;
import retrofit2.http.GET;
public interface KidsGamesApiCall {
@GET("kidsgames.json")
Call<ArrayList<MainImageItem>> getMainImageList();
}
(04) Activity (主要)-KidsGameActivity
package com.example.childrenartsdrawing.activities;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
import com.example.childrenartsdrawing.adapter.KidsGameAdapter;
import com.example.childrenartsdrawing.common.Common;
import com.example.childrenartsdrawing.databinding.ActivityKidsGameBinding;
import com.example.childrenartsdrawing.interfaces.KidsGamesApiCall;
import com.example.childrenartsdrawing.interfaces.KidsGamesItemClick;
import com.example.childrenartsdrawing.models.MainImageItem;
import java.util.ArrayList;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class KidsGameActivity extends AppCompatActivity implements KidsGamesItemClick {
ActivityKidsGameBinding binding;
ArrayList<MainImageItem> mainImageItems = new ArrayList<>();
KidsGameAdapter adapter;
Retrofit retrofit;
KidsGamesApiCall services;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
binding = ActivityKidsGameBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
init();
toolBarClick();
}
private void init() {
binding.myToolbar.tvTitle.setText("Kids Game");
binding.myToolbar.icActionSetting.setVisibility(View.INVISIBLE);
callImageAPI();
}
private void toolBarClick() {
binding.myToolbar.icActionBack.setOnClickListener(v -> {
onBackPressed();
Common.myButtonSound(this);
});
}
private void callImageAPI() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
retrofit = new Retrofit.Builder()
.baseUrl("https://___________.in/childrenart/")
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
services = retrofit.create(KidsGamesApiCall.class);
drawingData();
}
private void drawingData() {
Call<ArrayList<MainImageItem>> call = services.getMainImageList();
call.enqueue(new Callback<ArrayList<MainImageItem>>() {
@Override
public void onResponse(@NonNull Call<ArrayList<MainImageItem>> call, @NonNull Response<ArrayList<MainImageItem>> response) {
if (response.isSuccessful()) {
mainImageItems = response.body();
Common.mainListImage = mainImageItems; // save received list in Common
if (Common.mainListImage != null) {
initRecyclerView(); // Here we set adapter
binding.llProgress.setVisibility(View.GONE);
}
}
}
@Override
public void onFailure(@NonNull Call<ArrayList<MainImageItem>> call, @NonNull Throwable t) {
Toast.makeText(KidsGameActivity.this, "Please Check Your Internet Connection", Toast.LENGTH_SHORT).show();
}
});
}
private void initRecyclerView() {
adapter = new KidsGameAdapter(KidsGameActivity.this, mainImageItems, this);
GridLayoutManager layoutManager = new GridLayoutManager(KidsGameActivity.this, 2);
binding.rvDrawingBookList.setLayoutManager(layoutManager);
binding.rvDrawingBookList.setAdapter(adapter);
}
private void passDrawingPosition(int position) {
Intent intent = new Intent(this, KidsGameListActivity.class);
intent.putExtra("KIDS_GAME_POSITION", position);
overridePendingTransition(0, 0);
startActivity(intent);
}
@Override
public void OnKidsGameItemClick(MainImageItem kidsGameItem, int position) {
Common.myBtnCategorySound(this);
passDrawingPosition(position);
}
@Override
protected void onStart() {
super.onStart();
if (Common.homeMusic != null)
Common.homeMusic.start();
}
@Override
protected void onPause() {
super.onPause();
Common.homeMusic.pause();
}
@Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
}
(05) Activity (MainXML 布局)- Activity_kids_game 您可以为custom_action_bar制作自定义布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_drawing"
android:gravity="center"
android:orientation="vertical"
tools:context=".activities.DrawingBookActivity">
<include
android:id="@+id/my_toolbar"
layout="@layout/custom_action_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
app:layout_constraintBottom_toTopOf="@+id/llDrawingBook"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.083"
tools:layout_editor_absoluteX="10dp" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/llProgress"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.airbnb.lottie.LottieAnimationView
android:layout_width="168dp"
android:layout_height="217dp"
android:layout_gravity="bottom"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:lottie_autoPlay="true"
app:lottie_imageAssetsFolder="images"
app:lottie_loop="true"
app:lottie_rawRes="@raw/progress_2"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvDrawingBookList"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
(06) 类 - 普通
package com.example.childrenartsdrawing.common;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.media.MediaPlayer;
import com.example.childrenartsdrawing.R;
import com.example.childrenartsdrawing.models.MainImageItem;
import com.example.childrenartsdrawing.models.MyGalleryItem;
import java.util.ArrayList;
import java.util.Random;
public class Common {
// Here we store MainImageItem in array list
public static ArrayList<MainImageItem> mainListImage;
public static int musicHome, buttonSound, btnCancel,buttonDelete;
public static MediaPlayer homeMusic, buttonClickSound,mpCancel, mpClickSound,mpBtnBig,mpBtnCategory,mpItemSound,deleteSound;
public static Boolean soundOn = true;
public static ArrayList<MyGalleryItem> MY_GALLERY_IMAGES;
public static void myMusicStart(Context mContext) {
musicHome = R.raw.music12bg;
homeMusic = MediaPlayer.create(mContext, musicHome);
homeMusic.start();
}
public static void myButtonSound(Context mContext) {
if (Common.soundOn) {
buttonSound = R.raw.sound_btn_play;
buttonClickSound = MediaPlayer.create(mContext, buttonSound);
buttonClickSound.start();
}
}
public static void onClickSound(Context mContext) {
if (Common.soundOn) {
Random random = new Random();
int[] myMusic = {R.raw.music_01, R.raw.music_02, R.raw.music_03, R.raw.music_04, R.raw.music_05, R.raw.music_06, R.raw.music_07, R.raw.music_08, R.raw.music_09, R.raw.music_10, R.raw.music_11};
int i = random.nextInt(myMusic.length);
mpClickSound = MediaPlayer.create(mContext, myMusic[i]);
mpClickSound.start();
}
}
}
(07) 自定义布局 - item_main_image
<?xml version="1.0" encoding="utf-8"?><!-- 2 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/llCustomDrawAct"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="@color/transparent">
<ImageView
android:id="@+id/ivMainItem"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"/>
</LinearLayout>
(08) 适配器 - KidsGameAdapter
package com.example.childrenartsdrawing.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.example.childrenartsdrawing.databinding.ItemMainImageBinding;
import com.example.childrenartsdrawing.interfaces.KidsGamesItemClick;
import com.example.childrenartsdrawing.models.MainImageItem;
import java.util.ArrayList;
public class KidsGameAdapter extends RecyclerView.Adapter<KidsGameAdapter.MyViewHolder> {
ItemMainImageBinding binding;
private Context context;
private ArrayList<MainImageItem> itemList;
// i3 & create constructor also
private KidsGamesItemClick setMainItemClick;
public KidsGameAdapter(Context context, ArrayList<MainImageItem> itemList, KidsGamesItemClick setMainItemClick) {
this.context = context;
this.itemList = itemList;
this.setMainItemClick = setMainItemClick;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
binding = ItemMainImageBinding.inflate(LayoutInflater.from(context),parent,false);
MyViewHolder holder = new MyViewHolder(binding);
return holder;
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
MainImageItem item = itemList.get(position);
// holder.binding.tvMainItem.setText(item.getCategoryName());
Glide.with(context).load(item.getProfileImage()).into(holder.binding.ivMainItem);
// i4
holder.binding.ivMainItem.setOnClickListener(view -> setMainItemClick.OnKidsGameItemClick(item,position));
}
@Override
public int getItemCount() {
return itemList.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
ItemMainImageBinding binding;
public MyViewHolder(@NonNull ItemMainImageBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
}
(09) 界面 - KidsGamesItemClick
package com.example.childrenartsdrawing.interfaces;
import com.example.childrenartsdrawing.models.MainImageItem;
public interface KidsGamesItemClick {
void OnKidsGameItemClick(MainImageItem kidsGameItem, int position);
}
(10) Activity (主要)-KidsGameListActivity
package com.example.childrenartsdrawing.activities;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
import com.example.childrenartsdrawing.adapter.KidsGameListAdapter;
import com.example.childrenartsdrawing.common.Common;
import com.example.childrenartsdrawing.databinding.ActivityKidsGameListBinding;
import com.example.childrenartsdrawing.interfaces.KidsGamesListItemClick;
import com.example.childrenartsdrawing.models.SubImageItem;
public class KidsGameListActivity extends AppCompatActivity implements KidsGamesListItemClick {
ActivityKidsGameListBinding binding;
int mMainListPos;
KidsGameListAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
binding = ActivityKidsGameListBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
mMainListPos = getIntent().getIntExtra("KIDS_GAME_POSITION", 0);
init();
toolBarClick();
binding.myToolbar.icActionSetting.setVisibility(View.GONE);
}
private void init() {
initRecyclerView();
}
private void initRecyclerView() {
adapter = new KidsGameListAdapter(this, Common.mainListImage.get(mMainListPos).getCategoryImages(), this);
LinearLayoutManager layoutManager = new GridLayoutManager(this, 2, GridLayoutManager.VERTICAL, false);
binding.rvSubList.setLayoutManager(layoutManager);
binding.rvSubList.setAdapter(adapter);
}
@Override
protected void onStart() {
super.onStart();
if (Common.homeMusic != null)
Common.homeMusic.start();
}
@Override
protected void onPause() {
super.onPause();
if (Common.homeMusic != null)
Common.homeMusic.pause();
}
private void toolBarClick() {
binding.myToolbar.icActionBack.setOnClickListener(v -> {
onBackPressed();
Common.myButtonSound(this);
});
}
@Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void setKidsListSubItemClick(SubImageItem subImageItem, int position) {
String subImageUrl = subImageItem.getImageUrl();
String activityName = KidsGameListActivity.class.getSimpleName();
Intent myIntent = new Intent(this, PaintDrawActivity.class);
Bundle bundle = new Bundle();
bundle.putString("ACTIVITY_NAME",activityName);
bundle.putString("SUB_IMAGE_URL", subImageUrl);
bundle.putInt("SUB_IMAGE_POSITION", position);
bundle.putInt("MAIN_IMAGE_POSITION", mMainListPos);
myIntent.putExtras(bundle);
Common.myBtnItemSound(this);
startActivityForResult(myIntent, 0);
}
}
(11) Activity (MainXML-布局)-activity_kids_game_list
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/bg_drawing"
tools:context=".activities.DrawingBookListActivity">
<LinearLayout
android:id="@+id/llLoader"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:visibility="gone"
android:orientation="vertical">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<include
android:id="@+id/my_toolbar"
layout="@layout/custom_action_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
app:layout_constraintBottom_toTopOf="@+id/llDrawingBook"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.083"
tools:layout_editor_absoluteX="10dp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvSubList"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
(12) 自定义布局 - item_sub_image
<?xml version="1.0" encoding="utf-8"?><!-- 2 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/card_click"
android:layout_width="match_parent"
android:layout_height="160dp"
android:layout_gravity="center"
android:foreground="?android:attr/selectableItemBackground"
android:orientation="horizontal"
android:padding="5dp"
android:layout_margin="10dp">
<LinearLayout
android:background="@drawable/ic_image_background"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/ivSubItem"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp"
android:layout_margin="10dp"/>
</LinearLayout>
</LinearLayout>
(13) 适配器 - KidsGameListAdapter
package com.example.childrenartsdrawing.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.example.childrenartsdrawing.databinding.ItemSubImageBinding;
import com.example.childrenartsdrawing.interfaces.KidsGamesListItemClick;
import com.example.childrenartsdrawing.models.SubImageItem;
import java.util.ArrayList;
public class KidsGameListAdapter extends RecyclerView.Adapter<KidsGameListAdapter.MyViewHolder> {
ItemSubImageBinding binding;
private Context context;
private ArrayList<SubImageItem> itemList;
// i3 & create constructor also
private KidsGamesListItemClick subItemClick;
public KidsGameListAdapter(Context context, ArrayList<SubImageItem> itemList, KidsGamesListItemClick subItemClick) {
this.context = context;
this.itemList = itemList;
this.subItemClick = subItemClick;
}
@NonNull
@Override
public KidsGameListAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
binding = ItemSubImageBinding.inflate(LayoutInflater.from(context),parent,false);
KidsGameListAdapter.MyViewHolder holder = new KidsGameListAdapter.MyViewHolder(binding);
return holder;
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
SubImageItem item = itemList.get(position);
Glide.with(context).load(itemList.get(position).getImageUrl()).into(holder.binding.ivSubItem);
holder.binding.cardClick.setOnClickListener(view -> {
subItemClick.setKidsListSubItemClick(item,position);
});
}
@Override
public int getItemCount() {
return itemList.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
ItemSubImageBinding binding;
public MyViewHolder(@NonNull ItemSubImageBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
}
(14) 界面 - KidsGamesListItemClick
package com.example.childrenartsdrawing.interfaces;
import com.example.childrenartsdrawing.models.SubImageItem;
public interface KidsGamesListItemClick {
void setKidsListSubItemClick(SubImageItem subImageItem, int position);
}
关于android - 如何使用 View 绑定(bind) android 从嵌套 JSON 数组中获取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72771912/