利用PlaceHolderVidew库编写无限列表

文章介绍了如何处理包含福建师范大学学生信息的JSON数据,涉及Gson库的使用,如JSONArray和JSONObject的解析,以及如何将JSON数据结构转换为自定义的InfiniteFeedInfo模型对象,展示了模型绑定和数据填充的过程。

“grade” : “2016级”

},

{

“name” : “张瑞建”,

“image_url” : “https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=11813822,2468845429&fm=26&gp=0.jpg”,

“caption” : “福建师范大学法学院研究生,学号116072017030”,

“grade” : “2014级”

},

{

“name” : “闫少奇”,

“image_url” : “https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=11813822,2468845429&fm=26&gp=0.jpg”,

“caption” : “福建师范大学法学院研究生,学号116072017022”,

“grade” : “2015级”

},

{

“name” : “张少”,

“image_url” : “https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=11813822,2468845429&fm=26&gp=0.jpg”,

“caption” : “福建师范大学生命科学学院学生,学号116072017040”,

“grade” : “2018级”

},

{

“name” : “何文”,

“image_url” : “https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=11813822,2468845429&fm=26&gp=0.jpg”,

“caption” : “福建师范大学网络学院学生,学号116072017040”,

“grade” : “2018级”

},

{

“name” : “杨子琪”,

“image_url” : “https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=11813822,2468845429&fm=26&gp=0.jpg”,

“caption” : “福建师范大学文学院学生,学号116072017040”,

“grade” : “2018级”

},

{

“name” : “陈晨”,

“image_url” : “https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=11813822,2468845429&fm=26&gp=0.jpg”,

“caption” : “福建师范大学教育学生,学号116072017040”,

“grade” : “2017级”

},

{

“name” : “杨超”,

“image_url” : “https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=11813822,2468845429&fm=26&gp=0.jpg”,

“caption” : “福建师范大学音乐学院学生,学号116072017040”,

“grade” : “2018级”

},

{

“name” : “林志强”,

“image_url” : “https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=11813822,2468845429&fm=26&gp=0.jpg”,

“caption” : “福建师范大学生命科学学院学生,学号116072017040”,

“grade”: “2018级”

},

{

“name” : “叶存浩”,

“image_url” : “https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=11813822,2468845429&fm=26&gp=0.jpg”,

“caption” : “福建师范大学物理学院学生,学号116072017040”,

“grade” : “2018级”

},

{

“name”: “林振铭”,

“image_url” : “https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=11813822,2468845429&fm=26&gp=0.jpg”,

“caption” : “福建师范大学音乐学院学生,学号116072017040”,

“grade” : “2018级”

},

{

“name” : “林腾翔”,

“image_url” : “https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=11813822,2468845429&fm=26&gp=0.jpg”,

“name” : “福建师范大学文学院学生,学号116072017040”,

“grade” : “2018级”

}

]

笔记:

其实JSON数据就是一段字符串,只不过有不同意义的分隔符将其分割开来而已,其中

[] 代表的是一个数组;

{} 代表的是一个对象;

“ ” 表示的是属性值;

:代表的是前后之间的关系,冒号前面是属性的名称,后面是属性的值,这个值可以是基本数据类型,也可以是引用数据类型。

步骤6:创建Utils.java


utils.java包含解析种子json文件填充模型所需的方法InfiniteFeedInfo.java

public class Utils {

private static final String TAG = “Utils”;

public static List loadInfiniteFeeds(Context context){

try{

GsonBuilder builder = new GsonBuilder();

Gson gson = builder.create();

JSONArray array = new JSONArray(loadJSONFromAsset(context, “infinite_news.json”));

List feedList = new ArrayList<>();

for(int i=0;i<array.length();i++){

InfiniteFeedInfo feed = gson.fromJson(array.getString(i), InfiniteFeedInfo.class);

feedList.add(feed);

}

return feedList;

}catch (Exception e){

Log.d(TAG,"seedGames parseException " + e);

e.printStackTrace();

return null;

}

}

private static String loadJSONFromAsset(Context context, String jsonFileName) {

String json = null;

InputStream is=null;

try {

AssetManager manager = context.getAssets();

Log.d(TAG,"path "+jsonFileName);

is = manager.open(jsonFileName);

int size = is.available();

byte[] buffer = new byte[size];

is.read(buffer);

is.close();

json = new String(buffer, “UTF-8”);

} catch (IOException ex) {

ex.printStackTrace();

return null;

}

return json;

}

}

笔记:

如果要将一个json数据转换为对象的话需要使用fromJson(String json, Class classOfT) /fromJson(String json, Type typeOfT),当我们将对象转换为String的时候根据String toJson(Object src)方法。这里需要注意一点,如果response.body().string()调用大于一次的话,就会报错java.lang.IllegalStateException: closed,因为response.body().string()调用一次之后流就断掉了,需要重新构建一个response。

步骤7:建立模型InfiniteFeedInfo.java


public class InfiniteFeedInfo {

@SerializedName(“name”)

@Expose

private String name;

@SerializedName(“image_url”)

@Expose

private String imageUrl;

@SerializedName(“caption”)

@Expose

private String caption;

@SerializedName(“grade”)

@Expose

private String grade;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getImageUrl() {

return imageUrl;

}

public void setImageUrl(String imageUrl) {

this.imageUrl = imageUrl;

}

public String getCaption() {

return caption;

}

public void setCaption(String caption) {

this.caption = caption;

}

public String getGrade() {

return grade;

}

public void setGrade(String grade) {

this.grade = grade;

}

}

笔记:

1、首先说一下SerializedName的主要作用:属性重命名,可以将json中的属性名转为我们自己自定义的属性名其次@SerializedName注解提供了两个属性,上面用到了其中一个’value’,别外还有一个属性’alternate’:接收一个String数组,alternate数组中出现任意一个属性名都可以转换为自定义的属性,如果出现多个则以最后一个为准。@SerializedName 注解属于gson类,读取json文件变量并将其绑定到模型变量。

2、@Expose用于使变量对于gson的解析变为可读。

步骤8:现在,我们将创建类以绑定列表及其操作的项目视图。


ItemView.java 自定义生成JavaBean。

@Layout(R.layout.load_more_item_view)

public class ItemView {

@View(R.id.nameTxt)

private TextView nameTxt;

@View(R.id.captionTxt)

private TextView captionTxt;

@View(R.id.gradeTxt)

private TextView gradeTxt;

@View(R.id.imageView)

private ImageView imageView;

private InfiniteFeedInfo mInfo;

private Context mContext;

public ItemView(Context context, InfiniteFeedInfo info) {

mContext = context;

mInfo = info;

}

@Resolve

private void onResolved() {

nameTxt.setText(mInfo.getName());

captionTxt.setText(mInfo.getCaption());

gradeTxt.setText(mInfo.getGrade());

Glide.with(mContext).load(mInfo.getImageUrl()).into(imageView);

}

}

笔记:

  1. @layout 用于将xml布局与此类绑定。

  2. @View 用于将视图绑定到我们要引用的布局中。

  3. @Resolve当视图位于内存中时调用一个方法,以便用数据填充该视图。

  4. Glide 用法传承目前流行的链式调用,他的基础用法如下。

/**

  • 基础用法.

*/

private void baseUsed(){

Glide.with(this)

.load(URL)

.into(mImageView);

}

步骤9:现在,我们将创建类以绑定并定义“加载更多”视图。


创建LoadMoreView.java类,为了模拟从Internet延迟加载数据,我定义了ForcedWaitedLoading类。此类创建一个新线程,然后在2秒后,在UI线程中添加更多数据视图列表,该视图应始终从UI线程更新。

@Layout(R.layout.load_more_view)

public class LoadMoreView {

public static final int LOAD_VIEW_SET_COUNT = 6;

private InfinitePlaceHolderView mLoadMoreView;

private List mFeedList;

public LoadMoreView(InfinitePlaceHolderView loadMoreView, List feedList) {

this.mLoadMoreView = loadMoreView;

this.mFeedList = feedList;

}

@LoadMore

private void onLoadMore(){

Log.d(“DEBUG”, “onLoadMore”);

new ForcedWaitedLoading();

}

class ForcedWaitedLoading implements Runnable{

public ForcedWaitedLoading() {

new Thread(this).start();

}

@Override

public void run() {

try {

Thread.currentThread().sleep(2000);

}catch (InterruptedException e){

e.printStackTrace();

}

new Handler(Looper.getMainLooper()).post(new Runnable() {

@Override

public void run() {

int count = mLoadMoreView.getViewCount();

Log.d(“DEBUG”, "count " + count);

for (int i = count - 1;

i < (count - 1 + LoadMoreView.LOAD_VIEW_SET_COUNT) && mFeedList.size() > i;

i++) {

mLoadMoreView.addView(new ItemView(mLoadMoreView.getContext(), mFeedList.get(i)));

if(i == mFeedList.size() - 1){

mLoadMoreView.noMoreToLoad();

break;

}

}

mLoadMoreView.loadingDone();

}

});

}

}

}

笔记:

  1. @LoadMore当列表滚动到最后一项时,将调用此注释。任何获取更多数据的请求都会调用此带注释的方法。

  2. mLoadMoreView.loadingDone()当所有数据都已获取并且视图已填充新数据时,需要调用此方法。它将删除加载视图。

  3. mLoadMoreView.noMoreToLoad()提取数据后,应调用此方法。它将停用加载功能。

步骤10:创建 MainActivity.java


我们获取的实例使用InfiniteFeedInfo模型列表中的数据添加视图。

使用setLoadMoreResolver方法添加LoadMoreView要用作加载指示符的对象。

public class MainActivity extends AppCompatActivity {

private InfinitePlaceHolderView mLoadMoreView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mLoadMoreView = (InfinitePlaceHolderView)findViewById(R.id.loadMoreView);

setupView();

}

private void setupView(){

List feedList = Utils.loadInfiniteFeeds(this.getApplicationContext());

Log.d(“DEBUG”, "LoadMoreView.LOAD_VIEW_SET_COUNT " + LoadMoreView.LOAD_VIEW_SET_COUNT);

for(int i = 0; i < LoadMoreView.LOAD_VIEW_SET_COUNT; i++){

mLoadMoreView.addView(new ItemView(this.getApplicationContext(), feedList.get(i)));

}

mLoadMoreView.setLoadMoreResolver(new LoadMoreView(mLoadMoreView, feedList));

}

}

然后我们点击运行。


这样我们就完成了!!!

在这里插入图片描述

参考资料:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

总结

其实要轻松掌握很简单,要点就两个:

  1. 找到一套好的视频资料,紧跟大牛梳理好的知识框架进行学习。
  2. 多练。 (视频优势是互动感强,容易集中注意力)

你不需要是天才,也不需要具备强悍的天赋,只要做到这两点,短期内成功的概率是非常高的。

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。下面资料部分截图是我花费几个月时间整理的,诚意满满:特别适合有3-5年开发经验的Android程序员们学习。

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

mg-JmltGi5g-1711944353791)]

[外链图片转存中…(img-lVlP4z00-1711944353792)]

[外链图片转存中…(img-24M0P0MK-1711944353792)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

总结

其实要轻松掌握很简单,要点就两个:

  1. 找到一套好的视频资料,紧跟大牛梳理好的知识框架进行学习。
  2. 多练。 (视频优势是互动感强,容易集中注意力)

你不需要是天才,也不需要具备强悍的天赋,只要做到这两点,短期内成功的概率是非常高的。

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。下面资料部分截图是我花费几个月时间整理的,诚意满满:特别适合有3-5年开发经验的Android程序员们学习。

[外链图片转存中…(img-8YIHLX4R-1711944353792)]

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值