以下代码的功能主要有:
解析json文件中的json数组并将解析的Fruit对象添加到ArrayList中,再通过RecyclerView和adapter显示出来,其中item除了文字还有图片,基于Glide库。全部源码如下:
一:src/main/assets
jsoncontent.json
[
{
"name": "apple",
"imageId": "https://img1.baidu.com/it/u=1938446611,1287955047&fm=253&fmt=auto&app=138&f=JPEG?w=488&h=382"
},
{
"name": "Banana",
"imageId": "https://img1.baidu.com/it/u=3054655111,3404199589&fm=253&fmt=auto&app=138&f=JPEG?w=670&h=446"
},
{
"name": "watermelon",
"imageId": "https://img1.baidu.com/it/u=1938446611,1287955047&fm=253&fmt=auto&app=138&f=JPEG?w=488&h=382"
},
{
"name": "strawberry",
"imageId": "https://img1.baidu.com/it/u=3054655111,3404199589&fm=253&fmt=auto&app=138&f=JPEG?w=670&h=446"
}
]
二:Fruit
package com.tianqi.myapplication;
public class Fruit {
String name;
String imageId;
public Fruit(String name, String imageId) {
this.name = name;
this.imageId = imageId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImageId() {
return imageId;
}
public void setImageId(String imageId) {
this.imageId = imageId;
}
}
三:FruitAdapter
package com.tianqi.myapplication;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import java.util.List;
/**
* created by徐天骐
* date:2019/3/21
* describe:
**/
/**
因为FruitAdapter继承自RecyclerView.Adapter方法,所以该类必须
重写OnCreateViewHolder().OnBindViewHolder().getItemCount()
这三个方法
* */
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
private final List<Fruit> mFruitList;
public FruitAdapter(List<Fruit> fruitList) {
mFruitList = fruitList;
}
static class ViewHolder extends RecyclerView.ViewHolder {
ImageView fruitimg;
TextView textView;
public ViewHolder(View view) {
super(view);
fruitimg = view.findViewById(R.id.fruit_img);
textView = view.findViewById(R.id.fruit_name);
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int i) {
//(1)该方法用于加载子布局fruit_item,将创建的XML文件传给viewHolder文件
//(2)将view作为ViewHolder类的构造函数的参数,最后返回ViewHolder对象
View view = LayoutInflater.from(MyApplication.getContext()).inflate(R.layout.fruit_item1,parent,false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
//(1)该方法在每个子项滚动到屏幕内时执行
//(2)通过get(position)得到当前实列,并为其属性赋值。
Fruit fruit = mFruitList.get(position);
//当图片是AS项目的res文件夹下面的drawable文件夹中的文件时
//viewHolder.fruitimg.setImageResource(fruit.getImageId());
//当图片是拥有网络url的图片时
Glide.with(MyApplication.getContext()).load(fruit.getImageId()).override(500,500).into(viewHolder.fruitimg);
viewHolder.textView.setText(fruit.getName());
}
@Override
public int getItemCount() {
//该方法显示RecyclerView方法一共多少子项,直接返回数据源长度
return mFruitList.size();
}
}
四:MainActivity
package com.tianqi.myapplication;
import android.os.Bundle;
import com.google.gson.Gson;
import org.json.JSONArray;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.LinearLayoutManager;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private List<Fruit> mFruitList = new ArrayList<>();
private String jsonArrayString;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
RecyclerView recyclerView = findViewById(R.id.recyclerview);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
//上面是创建并设置 布局管理器
//下面是创建并设置 适配器
FruitAdapter adapter = new FruitAdapter(mFruitList);
recyclerView.setAdapter(adapter);
}
private void initData(){
Gson gson = new Gson();
try {
InputStream is = this.getAssets().open("jsoncontent.json");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
jsonArrayString = new String(buffer, "UTF-8");
JSONArray jsonArray = new JSONArray(jsonArrayString);
for(int i=0;i<jsonArray.length();i++){
Fruit fruit = gson.fromJson(jsonArray.get(i).toString(),Fruit.class);
mFruitList.add(fruit);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
五:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
六:fruit_item1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/fruit_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#AAAAAA"/>
</LinearLayout>
</LinearLayout>
七:AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tianqi.myapplication">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:name="com.tianqi.myapplication.MyApplication"
android:theme="@style/Theme.MyApplication">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
八:MyApplication
package com.tianqi.myapplication;
import android.app.Application;
import android.content.Context;
public class MyApplication extends Application {
private static Context context;
@Override
public void onCreate() {
context = getApplicationContext();
}
public static Context getContext() {
return context;
}
}
九:注意事项
1:多个json对象的最外层是[ ],不是{ }。
2:适配器的构造方法
public FruitAdapter(Context context,List<Fruit> fruitList){ }添加了Context参数。
3:适配器创建了全局变量:private LayoutInflater inflater;4:Glide.with(context).load(fruit.getImageId()).override(500,500).into(viewHolder.fruitimg);
使用Glide库时with的参数此处是context,override的参数指定图片的长和宽
5:解析json的部分代码
InputStream is = this.getAssets().open("jsoncontent.json");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
jsonArrayString = new String(buffer, "UTF-8");
JSONArray jsonArray = new JSONArray(jsonArrayString);
for(int i=0;i<jsonArray.length();i++){
Fruit fruit = gson.fromJson(jsonArray.get(i).toString(),Fruit.class);
mFruitList.add(fruit);6:Glide加载网络图片需要对用权限:
<uses-permission android:name="android.permission.INTERNET" />
7:对应的import class要替换成androidx,如:
import androidx.recyclerview.widget.RecyclerView;8:build.gradle文件需要对应的implementation,如:
implementation 'com.google.code.gson:gson:2.8.7' implementation 'com.github.bumptech.glide:glide:4.11.0'9:MyApplication类的前面必须加上public关键字,否则会报错如下:
XXX is not accessible from java.lang.Class android.app.AppComponentFactory
十:关于全局获取Context的技巧
Android提供了一个Application类,每当应用程序启动的时候,系统就会自动将这个类进行初始化,而我们可以定制自己的Application类,以便于管理程序内一些全局的状态信息,比如全局Context。定制的MyApplication的代码如上第八条,重写onCreate方法,再提供静态的getContext()方法,在这里将Context进行返回。
下一步需要告知系统,程序启动应该初始化MyApplication类,而不是默认的Application类,具体步骤:在AndroidManifest.xml中,加上如下的一行代码:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:name="com.tianqi.myapplication.MyApplication"
android:theme="@style/Theme.MyApplication">