Android 移除视图时暂停观察者
Android pause an observer when view is removed
我有两个自定义视图(canvas 视图),它们都有一个观察器,可以触发屏幕上的事件并在 canvas 上绘制一些东西。我正在重用容器并通过删除其他视图在同一父布局中呈现 canvas。现在,无论我的两个观察者价值观如何。
我尝试了一个肮脏的 hack,我将一个 boolan 传递给两个视图,一个是 true,另一个是 false,这有点工作,但我不希望那样。因为它只是一个 hack。谁能告诉我 android 的方法吗?
public class FakeViewOne extends View {
private EventViewModel eventViewModel;
private float l = 0.0f;
public FakeViewOne(Context context, View ParentView) {
super(context);
eventViewModel = new ViewModelProvider((ViewModelStoreOwner) getContext()).get(EventViewModel.class);
eventViewModel.getTrigger().observe((LifecycleOwner) getContext(), new Observer<Float>() {
@Override
public void onChanged(Float val) {
l = val;
}
});
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
/*
* if l > 50 change background of a linearlayout
* draw a line on a canvas
* */
invalidate();
}
}
public class FakeViewTwo extends View {
private EventViewModel eventViewModel;
private float l = 0.0f;
public FakeViewTwo(Context context, View ParentView) {
super(context);
eventViewModel = new ViewModelProvider((ViewModelStoreOwner) getContext()).get(EventViewModel.class);
eventViewModel.getTrigger().observe((LifecycleOwner) getContext(), new Observer<Float>() {
@Override
public void onChanged(Float val) {
l = val;
}
});
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
/*
* if l > 50 change background of a tile
*
* */
invalidate();
}
}
CODE 在片段内,我在这两个 FakeView 之间切换。当它们在视图中 not-rendered/inactive/removed 时,我怎样才能让它们不观察值。我正在使用 mycanvas.removeAllViews();.
final RelativeLayout mycanvas = view.findViewById(R.id.myCanvas);
gestureViewModel.getGestureType().observe(getActivity(), new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
assert s != null;
mycanvas.removeAllViews();
switch (s){
case "shake":
ShakeControl(view,myView,mycanvas);
break;
case "move":
MoveControl(view,myView,mycanvas);
break;
}
}
});
我已经通过移除每个 FakeView 中 window 分离的观察者解决了这个问题。
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
Log.d("Detached","Head");
if (eventViewModel != null && eventViewModel.getTrigger().hasObservers()) {
eventViewModel.getTrigger().removeObservers((LifecycleOwner) ctx);
}
}
我有两个自定义视图(canvas 视图),它们都有一个观察器,可以触发屏幕上的事件并在 canvas 上绘制一些东西。我正在重用容器并通过删除其他视图在同一父布局中呈现 canvas。现在,无论我的两个观察者价值观如何。
我尝试了一个肮脏的 hack,我将一个 boolan 传递给两个视图,一个是 true,另一个是 false,这有点工作,但我不希望那样。因为它只是一个 hack。谁能告诉我 android 的方法吗?
public class FakeViewOne extends View {
private EventViewModel eventViewModel;
private float l = 0.0f;
public FakeViewOne(Context context, View ParentView) {
super(context);
eventViewModel = new ViewModelProvider((ViewModelStoreOwner) getContext()).get(EventViewModel.class);
eventViewModel.getTrigger().observe((LifecycleOwner) getContext(), new Observer<Float>() {
@Override
public void onChanged(Float val) {
l = val;
}
});
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
/*
* if l > 50 change background of a linearlayout
* draw a line on a canvas
* */
invalidate();
}
}
public class FakeViewTwo extends View {
private EventViewModel eventViewModel;
private float l = 0.0f;
public FakeViewTwo(Context context, View ParentView) {
super(context);
eventViewModel = new ViewModelProvider((ViewModelStoreOwner) getContext()).get(EventViewModel.class);
eventViewModel.getTrigger().observe((LifecycleOwner) getContext(), new Observer<Float>() {
@Override
public void onChanged(Float val) {
l = val;
}
});
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
/*
* if l > 50 change background of a tile
*
* */
invalidate();
}
}
CODE 在片段内,我在这两个 FakeView 之间切换。当它们在视图中 not-rendered/inactive/removed 时,我怎样才能让它们不观察值。我正在使用 mycanvas.removeAllViews();.
final RelativeLayout mycanvas = view.findViewById(R.id.myCanvas);
gestureViewModel.getGestureType().observe(getActivity(), new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
assert s != null;
mycanvas.removeAllViews();
switch (s){
case "shake":
ShakeControl(view,myView,mycanvas);
break;
case "move":
MoveControl(view,myView,mycanvas);
break;
}
}
});
我已经通过移除每个 FakeView 中 window 分离的观察者解决了这个问题。
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
Log.d("Detached","Head");
if (eventViewModel != null && eventViewModel.getTrigger().hasObservers()) {
eventViewModel.getTrigger().removeObservers((LifecycleOwner) ctx);
}
}