上一篇
安卓开发手机数据显示
- 行业动态
- 2025-04-21
- 2
数据获取与处理
网络请求获取数据
工具:
Retrofit
、OkHttp
、Volley
示例(Retrofit + Gson):
// 定义API接口 public interface ApiService { @GET("path/to/data") Call<List<DataModel>> getData(); } // 创建Retrofit实例 Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://example.com/") .addConverterFactory(GsonConverterFactory.create()) .build(); // 发起请求 ApiService apiService = retrofit.create(ApiService.class); apiService.getData().enqueue(new Callback<List<DataModel>>() { @Override public void onResponse(Call<List<DataModel>> call, Response<List<DataModel>> response) { if (response.isSuccessful()) { List<DataModel> data = response.body(); // 更新UI } } @Override public void onFailure(Call<List<DataModel>> call, Throwable t) { // 处理错误 } });
本地数据库读取数据
工具:
Room
、SQLite
示例(Room):
// 定义实体类 @Entity public class User { @PrimaryKey(autoGenerate = true) public int id; public String name; } // 定义DAO @Dao public interface UserDao { @Query("SELECT FROM user") List<User> getAllUsers(); } // 使用LiveData观察数据变化 UserDao userDao = AppDatabase.getInstance(context).userDao(); userDao.getAllUsers().observe(lifecycleOwner, users -> { // 更新UI });
UI组件与数据显示
RecyclerView vs ListView
特性 | RecyclerView | ListView |
---|---|---|
性能 | 支持局部刷新,复用更高效 | 每次滚动需重新绘制所有Item |
布局灵活性 | 支持横向/纵向、多布局类型 | 仅支持纵向列表 |
扩展性 | 支持自定义动画、拖拽排序 | 功能较单一 |
RecyclerView使用步骤
添加依赖:
implementation 'androidx.recyclerview:recyclerview:1.3.0'
布局文件:
<androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent"/>
创建Adapter:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { private List<DataModel> dataList; public MyAdapter(List<DataModel> data) { this.dataList = data; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_layout, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(ViewHolder holder, int position) { DataModel data = dataList.get(position); holder.textView.setText(data.getName()); } @Override public int getItemCount() { return dataList.size(); } public static class ViewHolder extends RecyclerView.ViewHolder { TextView textView; public ViewHolder(View itemView) { super(itemView); textView = itemView.findViewById(R.id.textView); } } }
设置Adapter:
RecyclerView recyclerView = findViewById(R.id.recyclerView); MyAdapter adapter = new MyAdapter(dataList); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(adapter);
数据绑定与刷新
LiveData与ViewModel结合
作用:实现数据与UI的解耦,避免内存泄漏。
示例:
// ViewModel中定义LiveData public class MyViewModel extends ViewModel { private MutableLiveData<List<DataModel>> dataList = new MutableLiveData<>(); public LiveData<List<DataModel>> getDataList() { return dataList; } public void loadData() { // 模拟网络请求后更新数据 dataList.postValue(fetchDataFromNetwork()); } } // Activity中观察数据变化 MyViewModel viewModel = new ViewModelProvider(this).get(MyViewModel.class); viewModel.getDataList().observe(this, data -> { // 更新RecyclerView的Adapter adapter.submitList(data); });
分页加载(Paging 3)
适用场景:大量数据分页显示,减少内存占用。
核心组件:
PagingSource
:定义数据加载逻辑。PagingDataAdapter
:适配分页数据。
示例:
// 定义PagingSource public class MyPagingSource extends PagingSource<Integer, DataModel> { @Override public PagingState<Integer, DataModel> getRefreshKey() { return new PagingState<>(0, null, 0); // 从第0页开始 } @Override public LoadResult<Integer, DataModel> load(LoadParams<Integer> params) { int page = params.getKey(); List<DataModel> data = fetchDataFromNetwork(page); return new LoadResult.Page<>(data, null, page + 1); } }
常见问题与解决方案
问题 | 解决方案 |
---|---|
图片加载卡顿 | 使用Glide 或Picasso 加载图片,配合缓存策略(如DiskCache )。 |
RecyclerView滑动不流畅 | 开启硬件加速; 减少Item过度绘制; 使用 DiffUtil 优化数据更新。 |
数据重复加载 | 确保网络请求或数据库查询时去重(如通过唯一ID 判断)。 |
空数据处理 | 在Adapter中添加emptyView ,当数据为空时显示提示界面。 |
相关问题与解答
问题1:如何优化RecyclerView的性能?
解答:
- 复用ViewHolder:确保
onCreateViewHolder
只创建必要视图。 - 避免频繁调用
notifyDataSetChanged
:改用DiffUtil
对比数据差异,仅更新变化部分。 - 图片优化:使用
Glide
的fitCenter
裁剪,避免OOM。 - 预取数据:在用户滑动前提前加载相邻Item的数据。
问题2:如何处理网络请求失败的情况?
解答:
- 错误分类:区分网络错误(如断网)与服务器错误(如500)。
- 重试机制:使用
Retrofit
的retryWhen
或自定义重试逻辑(如点击重试按钮)。 - 本地缓存:在网络失败时读取本地缓存数据(如Room数据库)。
- 用户提示:通过
Toast
或Snackbar
告知用户错误