【Android开发基础】Fragment(碎片)中ViewModel的使用
文章目录
一、简述
- 描述:当Activity / Fragment数据处理量大时,一个XXActivity.java / XXFragment.java里就会有庞大的数据量。而这两者的主要作用应该是起到连接UI控件、渲染数据的作用,所以这就违背“单一负责”原则,那么数据就应该单独进行存放以及读取。为此Android官方就为开发者提供了ViewModel类。
- 难度:初级
- 知识点:
- 1、了解Java中数据存储地址的概念(逻辑 and 物理)
- 2、了解软件体系结构里的观察者模式
- 3、适配器(Adapter)的使用
- 4、认识ViewModel
二、创建ViewModel
为了使文章简洁,这里就直接使用Android studio配置好了的Bottom Navigation Activity
创建好工程后,就可以看到已经配置好了的ViewModel
三、了解LiveData
LiveData对于初学者而言,还是比较难以理解,这里会用就好了。
主要作用:通知Observe类将最新数据传递给渲染方法(和Vue里的双向绑定v-model有异曲同工之妙),实体类里通过postValue(this)监听数据变化,这在软件体系结构里被称为观察者模式。
ViewModel观察者模式
四、使用ViewModel
1、单体数据
如,创建初始的样子
这个很简单,直接跳过,平常就可以按照这个模板来。
2、实体类数据
很显然,任何在应用商店的Android app,不可能只是对单一数据进行渲染。必然牵扯到实体类数据(服务器发送json -> Android接收json -> json转实体)
(1)创建LiveData实体
这里以商品实体类为例(这是后面将写的博客购物车功能模块的实体类)
import androidx.lifecycle.LiveData;public class Shop extends LiveData<Shop> { int id; String image; String name; int price; String bus; float dis; String time; String des; public int getId() { return id; } public String getImage() { return image; } public String getName() { return name; } public int getPrice() { return price; } public String getBus() { return bus; } public float getDis() { return dis; } public String getTime() { return time; } public String getDes() { return des; } public void setId(int id) { this.id = id; postValue(this); } public void setImage(String image) { this.image = image; postValue(this); } public void setName(String name) { this.name = name; postValue(this); } public void setPrice(int price) { this.price = price; postValue(this); } public void setBus(String bus) { this.bus = bus; postValue(this); } public void setDis(float dis) { this.dis = dis; postValue(this); } public void setTime(String time) { this.time = time; postValue(this); } public void setDes(String des) { this.des = des; postValue(this); }}
(2)编写ViewModel
这里以模板里的HomeFragment和HomeViewModel为例
- HomeViewModel.java
import androidx.lifecycle.ViewModel;import com.hngy.xpq.shoppingcartmodule.bean.Shop;import java.util.ArrayList;import java.util.List;public class HomeViewModel extends ViewModel { private Shop shop = new Shop(); private List<Shop> ls; public List<Shop> getListShop() { ls = new ArrayList<>(); // 这里是获取数据,一般有三种方式 // 1、手动填充数据(测试) // 2、HTTP获取服务器数据 // 3、本地数据库存储的数据 for (int i = 0; i < 5;i++) { Shop s = new Shop(); s.setName("name" + i); s.setPrice(10 + i); s.setBus("商家" + i); s.setDis(Float.valueOf("2.55") + i); s.setTime("周" + i); s.setDes("无"); ls.add(s); } // ------------end---------- // return ls; } // 测试数据的改变,会不会影响视图显示的数据 public void xg() { // 修改数据(不通过setText方法) // 需要明白 Java数据地址原理 ls.get(1).setName("ViewModel绑定数据修改!"); }}
- HomeFragment.java
学习此节前,需要先学习栏目【Android开发基础】三种常见的适配器(Adapter)中List适配器。也可以复制附件中关于适配器的代码
private RecyclerView listShop; private List<Shop> shopList; private void init(View root) { shopList = homeViewModel.getListShop(); listShop = root.findViewById(R.id.listShop); getListAdapter(); // 数据渲染 homeViewModel.xg(); // 修改数据 } // List适配器 private void getListAdapter() { StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(1,StaggeredGridLayoutManager.VERTICAL); listShop.setLayoutManager(layoutManager); ListAdapter adapter = new ListAdapter(shopList); listShop.setAdapter(adapter); }
- 效果
五、附件
1、适配器UI界面设计代码
item_list.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="15dp" android:orientation="horizontal"> <ImageView android:id="@+id/homeImage" android:layout_width="120dp" android:layout_height="120dp" android:background="@drawable/ic_launcher_background"/> <TextView android:id="@+id/homeName" android:layout_width="match_parent" android:layout_height="25dp" android:layout_marginLeft="18dp" android:layout_toEndOf="@+id/homeImage" android:textSize="50px"/> <TextView android:id="@+id/homeTime" android:layout_width="150dp" android:layout_height="25dp" android:layout_below="@+id/homeName" android:layout_marginStart="16dp" android:layout_marginLeft="18dp" android:layout_marginTop="5dp" android:layout_toEndOf="@+id/homeImage" android:textSize="50px" /> <TextView android:id="@+id/homeDes" android:layout_width="150dp" android:layout_height="25dp" android:layout_below="@+id/homeTime" android:layout_marginStart="16dp" android:layout_marginLeft="18dp" android:layout_marginTop="5dp" android:layout_toEndOf="@+id/homeImage" android:textSize="50px" /> <TextView android:id="@+id/homePrice" android:layout_width="150dp" android:layout_height="25dp" android:layout_below="@+id/homeDes" android:layout_marginStart="16dp" android:layout_marginLeft="18dp" android:layout_marginTop="5dp" android:layout_toEndOf="@+id/homeImage" android:textSize="50px" /> <LinearLayout android:layout_width="match_parent" android:layout_height="120dp" android:gravity="bottom|right" android:paddingBottom="20dp"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="加入"/> LinearLayout>RelativeLayout>
2、适配器数据绑定代码
ListAdapter.java
import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.ListView;import android.widget.TextView;import androidx.annotation.NonNull;import androidx.recyclerview.widget.RecyclerView;import com.hngy.xpq.shoppingcartmodule.R;import com.hngy.xpq.shoppingcartmodule.bean.Shop;import java.util.List;public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder> { private List<Shop> listData; static class ViewHolder extends RecyclerView.ViewHolder { View fileView; ImageView image; TextView name, price, dis, time, des; public ViewHolder(View itemView) { super(itemView); fileView = itemView; name = itemView.findViewById(R.id.homeName); price = itemView.findViewById(R.id.homePrice); time = itemView.findViewById(R.id.homeTime); des = itemView.findViewById(R.id.homeDes); } } // 获取到数据 public ListAdapter(List<Shop> list) { this.listData = list; } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list,parent,false); final ViewHolder holder = new ViewHolder(view); return holder; } @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { // 数据绑定 final Shop s = listData.get(position); holder.name.setText(s.getName()); holder.price.setText("¥" + s.getPrice()); holder.time.setText(s.getTime()); holder.des.setText(s.getDes()); } @Override public int getItemCount() { return listData.size(); }}
来源地址:https://blog.csdn.net/weixin_48916759/article/details/130633430
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341