OnGlobalLayoutListener: устаревание и совместимость
Мне нужно использовать объект OnGlobalLayoutListener
, а затем удалить слушателя, у меня возникла проблема с устаревшими методами, которые я разрешаю с помощью следующего кода.
protected void onCreate(Bundle savedInstanceState) {
final LinearLayout llTotal = (LinearLayout) findViewById(R.id.mmc_ll);
ViewTreeObserver vto = llTotal.getViewTreeObserver();
if(vto.isAlive()){
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//
// mycode
//
if (Build.VERSION.SDK_INT<16) {
removeLayoutListenerPre16(llTotal.getViewTreeObserver(),this);
} else {
removeLayoutListenerPost16(llTotal.getViewTreeObserver(), this);
}
}
});
}
super.onCreate(savedInstanceState);
}
@SuppressWarnings("deprecation")
private void removeLayoutListenerPre16(ViewTreeObserver observer, OnGlobalLayoutListener listener){
observer.removeGlobalOnLayoutListener(listener);
}
@TargetApi(16)
private void removeLayoutListenerPost16(ViewTreeObserver observer, OnGlobalLayoutListener listener){
observer.removeOnGlobalLayoutListener(listener);
}
Правильно ли это? Существует лучший способ справиться с совместимостью?
Запуск кода в эмуляторе с API 10 У меня есть следующее предупреждение в LogCat
04-24 09:30:12.565: I/dalvikvm(471): Could not find method android.view.ViewTreeObserver.removeOnGlobalLayoutListener, referenced from method com.my.project.ActivityHome.removeLayoutListenerPost16
04-24 09:30:12.565: W/dalvikvm(471): VFY: unable to resolve virtual method 2950: Landroid/view/ViewTreeObserver;.removeOnGlobalLayoutListener (Landroid/view/ViewTreeObserver$OnGlobalLayoutListener;)V
Могу ли я игнорировать их, я должен что-то исправить?
Ответы
Ответ 1
Я использую это в своем проекте:
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static void removeOnGlobalLayoutListener(View v, ViewTreeObserver.OnGlobalLayoutListener listener){
if (Build.VERSION.SDK_INT < 16) {
v.getViewTreeObserver().removeGlobalOnLayoutListener(listener);
} else {
v.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
}
}
похож на ваш.
Протестировано на разных устройствах (4.2.2 и 2.3.3), и оно работает отлично.
Кажется, это единственный способ... Если вы найдете что-нибудь еще, я бы хотел это знать.
удачи
Ответ 2
Я думаю, что правильный способ - использовать Build.VERSION.SDK_INT
и Build.VERSION_CODES
:
public static void removeOnGlobalLayoutListener(View v, ViewTreeObserver.OnGlobalLayoutListener listener){
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
v.getViewTreeObserver().removeGlobalOnLayoutListener(listener);
} else {
v.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
}
}
Ответ 3
Конечно, проверка версии Android и вызов правильного метода гораздо более осмотрительны, но если вы посмотрите на исходный код Android, вы увидите что-то интересное:
@Deprecated
public void removeGlobalOnLayoutListener(OnGlobalLayoutListener victim) {
removeOnGlobalLayoutListener(victim);
}
Этот код был отключен от API 18
Ответ 4
mView.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
//noinspection deprecation
mView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
//
// mycode
//
}
});
Ответ 5
В соответствии с docs:
Этот метод устарел на уровне API 16. Вместо этого используйте #removeOnGlobalLayoutListener
Работает как шарм.