lin*_*age 10 android android-layout android-recyclerview lifecycleowner
考虑绑定到 viewModel 的布局数据。更具体地说,布局使用一个布局变量来访问这个底层的 viewModel。每当绑定膨胀时,它的 viewModel 和 lifeCycleOwner 都将被设置。(当然 viewModel 包含一些 liveData,直接绑定到一些视图属性)。
RecyclerView(在 Activity 中创建和设置)传递了一个 viewModel 列表。对于每个视图模型,一个 ViewHolder 是通过膨胀布局的新副本及其数据绑定来制作的。
该onBindViewHolder策略是
ViewHolder.dataBinding.setViewModel(viewModels[position])图。1。layout_counter.xml : 添加到 recyclerView 的单个组件的布局。
主视图模型.java
package com.gmail.example.rough;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
public class MainViewModel extends androidx.lifecycle.ViewModel {
private MutableLiveData<String> date, time, name;
public MainViewModel() {
this.date = new MutableLiveData<>(LocalDateTime.now().toString());
this.time = new MutableLiveData<>(LocalTime.now().toString());
this.name = new MutableLiveData<>(UUID.randomUUID().toString().substring(0,10));
Timer t=new Timer();
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
date.postValue(LocalDateTime.now().toString());
time.postValue(LocalTime.now().toString());
}
}, 0, 1000);
}
public LiveData<String> getDate() {
return date;
}
public LiveData<String> getTime() {
return time;
}
public LiveData<String> getName() {
return name;
}
}
Run Code Online (Sandbox Code Playgroud)
适配器.java
package com.gmail.example.rough;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.RecyclerView;
import com.gmail.example.rough.databinding.LayoutCounterBinding;
import java.util.List;
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
public static class ViewHolder extends RecyclerView.ViewHolder {
private LayoutCounterBinding binding;
public ViewHolder(@NonNull View itemView, LayoutCounterBinding binding) {
super(itemView);
this.binding = binding;
}
public LayoutCounterBinding getBinding() {
return binding;
}
}
List<MainViewModel> vms;
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.layout_counter, parent, false);
LayoutCounterBinding binding = DataBindingUtil.inflate(inflater, R.layout.layout_counter, parent, false);
return new ViewHolder(view, binding);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.getBinding().setVm(vms.get(position));
//how to set the LifeCycleOwner?
// holder.getBinding().setLifecycleOwner(???);
}
@Override
public int getItemCount() {
return vms.size();
}
public Adapter(List<MainViewModel> vms) {
this.vms = vms;
}
}
Run Code Online (Sandbox Code Playgroud)
主活动.java
package com.gmail.example.rough;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import android.os.Bundle;
import com.gmail.example.rough.databinding.LayoutMainBinding;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_main);
LayoutMainBinding binding = LayoutMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
ArrayList<MainViewModel> vms = new ArrayList<>();
vms.add(new MainViewModel());
vms.add(new MainViewModel());
vms.add(new MainViewModel());
binding.recyclerView.setAdapter(new Adapter(vms));
binding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
}
Run Code Online (Sandbox Code Playgroud)
layout_counter.xml
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="vm"
type="com.gmail.example.rough.MainViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".logger.android.MainActivity">
<TextView
android:id="@+id/tvName"
android:layout_width="wrap_content"
android:layout_height="19dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="@{vm.name}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<RelativeLayout
android:id="@+id/layoutRealtive"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:gravity="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvName">
<TextView
android:id="@+id/tvTs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="@id/tvTime"
android:layout_alignTop="@id/tvTime"
android:text="@{vm.date}" />
<TextView
android:id="@+id/tvTime"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:gravity="center"
android:textAlignment="center"
android:textSize="36sp"
android:textStyle="bold"
/>
<ImageView
android:id="@+id/ivReset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/tvTime"
android:layout_alignBottom="@id/tvTime"
android:layout_alignParentEnd="true"
android:src="@drawable/ic_launcher_foreground"
/>
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Run Code Online (Sandbox Code Playgroud)
布局_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="409dp"
android:layout_height="729dp"
android:layout_marginStart="1dp"
android:layout_marginTop="1dp"
android:layout_marginEnd="1dp"
android:layout_marginBottom="1dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Run Code Online (Sandbox Code Playgroud)
您可以参考下面的示例代码:
class SampleAdapter(private var list: List<String>,
private val viewmodel: SampleViewModel,
private val lifecycleOwner: LifecycleOwner) : RecyclerView.Adapter<SampleAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding: ItemRowBinding = DataBindingUtil.inflate(
LayoutInflater.from(parent.context),
R.layout.item_row, parent, false)
val holder= ViewHolder(binding, lifecycleOwner)
binding.lifecycleOwner=holder
holder.lifecycleCreate()
return holder
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind()
}
override fun getItemCount(): Int {
return list.size
}
override fun onViewAttachedToWindow(holder: ViewHolder) {
super.onViewAttachedToWindow(holder)
holder.attachToWindow()
}
inner class ViewHolder(private val binding: ItemRowBinding,
private var lifecycleOwner: LifecycleOwner)
: RecyclerView.ViewHolder(binding.root),LifecycleOwner {
private val lifecycleRegistry = LifecycleRegistry(this)
private var paused: Boolean = false
init {
lifecycleRegistry.currentState = Lifecycle.State.INITIALIZED
}
fun lifecycleCreate() {
lifecycleRegistry.currentState = Lifecycle.State.CREATED
}
override fun getLifecycle(): Lifecycle {
return lifecycleRegistry
}
fun bind() {
lifecycleOwner = this@SampleAdapter.lifecycleOwner
binding.viewmodel = viewmodel
binding.executePendingBindings()
}
fun attachToWindow() {
if (paused) {
lifecycleRegistry.currentState = Lifecycle.State.RESUMED
paused = false
} else {
lifecycleRegistry.currentState = Lifecycle.State.STARTED
}
}
}
fun setList(list: List<String>) {
this.list = list
notifyDataSetChanged()
} }
Run Code Online (Sandbox Code Playgroud)
我们之所以需要传递生命周期所有者是因为:ViewHolder不是生命周期所有者,这就是为什么它无法观察LiveData。整个想法是通过实现 LifecycleOwner 使 Viewholder 成为生命周期所有者,然后开始其生命周期。
| 归档时间: |
|
| 查看次数: |
3960 次 |
| 最近记录: |