有没有一种方法可以处理视图可见性的变化(例如,从 GONE 变为 VISIBLE),而无需覆盖视图呢?
类似于 View.setOnVisibilityChangeListener();
这样的东西吗?
有没有一种方法可以处理视图可见性的变化(例如,从 GONE 变为 VISIBLE),而无需覆盖视图呢?
类似于 View.setOnVisibilityChangeListener();
这样的东西吗?
您可以使用GlobalLayoutListener
来确定视图的可见性是否有任何更改。
myView.setTag(myView.getVisibility());
myView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int newVis = myView.getVisibility();
if((int)myView.getTag() != newVis)
{
myView.setTag(myView.getVisibility());
//visibility has changed
}
}
});
除了 @string.Empty 的解决方案之外,这是针对 Kotlin 的扩展实现。
fun View.visibilityChanged(action: (View) -> Unit) {
this.viewTreeObserver.addOnGlobalLayoutListener {
val newVis: Int = this.visibility
if (this.tag as Int? != newVis) {
this.tag = this.visibility
// visibility has changed
action(this)
}
}
}
按照以下方式实现
myView.visibilityChanged { view ->
when (view.visibility) {
VISIBLE -> { /* Do something here */ }
GONE -> { /* or here */ }
}
}
不需要使用子类化,可以使用装饰器:
class WatchedView {
static class Listener {
void onVisibilityChanged(int visibility);
}
private View v;
private Listener listener;
WatchedView(View v) {
this.v = v;
}
void setListener(Listener l) {
this.listener = l;
}
public setVisibility(int visibility) {
v.setVisibility(visibility);
if(listener != null) {
listener.onVisibilityChanged(visibility);
}
}
}
WatchedView v = new WatchedView(findViewById(R.id.myview));
v.setListener(this);
setVisibility()
,那么这种方法也可以起作用。 - string.Empty看一下 ViewTreeObserver.OnGlobalLayoutListener
。根据文档,它的回调方法 onGlobalLayout()
当全局布局状态或视图树中视图的可见性更改时被调用。因此,您可以尝试使用它来检测视图可见性变化。
TextView
的可见性。然后通过Flow/LiveData监听视图的可见性。class ViewModel : ViewModel() {
private val _textNameVisibility = MutableStateFlow(View.VISIBLE)
val textNameVisibility: LiveData<Int> = _textNameVisibility.asLiveData()
fun setTextNameVisibility(visibility: Int) {
_textNameVisibility.value = visibility
}
}
关于 Activity/Fragment
viewModel.textNameVisibility.observe(this) {
tvName.visibility = it
Log.i("TAG", "View visibility change" + it)
}
setTextNameVisibility
来更改视图的可见性。StateFlow
不会发出相同的值(类似于distinctUntilChanged
),因此不需要关心先前的可见性。import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.widget.ImageView
import android.widget.Toast
import java.lang.ref.WeakReference
class MyImageView : ImageView {
var mListener: WeakReference<VisibilityChangeListener>? = null
interface VisibilityChangeListener {
fun onVisibilityChanged(visibility: Int)
}
constructor(context: Context?) : super(context) {}
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {}
constructor(context: Context?, attrs: AttributeSet?, defStyle: Int) : super(
context,
attrs,
defStyle
) {
}
fun setVisibilityChangeListener(listener: VisibilityChangeListener) {
mListener = WeakReference(listener)
}
override fun onVisibilityChanged(changedView: View, visibility: Int) {
super.onVisibilityChanged(changedView, visibility)
Toast.makeText(context,visibility.toString(), Toast.LENGTH_SHORT).show()
if (mListener != null && changedView === this) {
val listener = mListener!!.get()
listener?.onVisibilityChanged(visibility)
}
}
}