ale*_*lex 30 android android-listview android-switch
在我的Android项目中,我有一个ListView包含SwitchCompat项目的行(AppCompat for Switchwidget).
当我滚动到列表并使用视图调用getView(...)方法时,我的问题发生.我重新定义了正确的状态,但动画是可见的.MyAdapterrecycledSwitch
在这种情况下有一个防止动画的解决方案?

小智 52
调用jumpDrawablesToCurrentState()将跳过动画.
ale*_*lex 12
我终于找到了一个解决方案,但似乎并不是很干净
ViewGroup viewGroup = (ViewGroup) view; // the recycled view
viewGroup.removeView(switch);
switch.setChecked(states[index]);
viewGroup.addView(switch);
Run Code Online (Sandbox Code Playgroud)
如果存在更好的解决方案,请分享.
我有同样的问题,我设法用一些最小的反射来解决它.
用法:
要在没有动画的情况下更改开关状态,请setChecked(boolean checked, boolean animate)为animate参数调用false方法.如果此方法在调用此方法时动画已经动画,则动画将停止并且开关跳转到所需位置.
SwitchCompatFix.java
import android.content.Context;
import android.support.v7.widget.SwitchCompat;
import android.util.AttributeSet;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Work around for: http://stackoverflow.com/questions/27139262/change-switch-state-without-animation
* Possible fix for bug 101107: https://code.google.com/p/android/issues/detail?id=101107
*
* Version 0.2
* @author Rolf Smit
*/
public class SwitchCompatFix extends SwitchCompat {
public SwitchCompatFix(Context context) {
super(context);
initHack();
}
public SwitchCompatFix(Context context, AttributeSet attrs) {
super(context, attrs);
initHack();
}
public SwitchCompatFix(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initHack();
}
private Method methodCancelPositionAnimator = null;
private Method methodSetThumbPosition = null;
private void initHack(){
try {
methodCancelPositionAnimator = SwitchCompat.class.getDeclaredMethod("cancelPositionAnimator");
methodSetThumbPosition = SwitchCompat.class.getDeclaredMethod("setThumbPosition", float.class);
methodCancelPositionAnimator.setAccessible(true);
methodSetThumbPosition.setAccessible(true);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
public void setChecked(boolean checked, boolean animate){
// Java does not support super.super.xxx calls, a call to the SwitchCompat default setChecked method is needed.
super.setChecked(checked);
if(!animate) {
// See original SwitchCompat source:
// Calling the super method may result in setChecked() getting called
// recursively with a different value, so load the REAL value...
checked = isChecked();
// Cancel any running animations (started by super.setChecked()) and immediately move the thumb to the new position
try {
if(methodCancelPositionAnimator != null && methodSetThumbPosition != null) {
methodCancelPositionAnimator.invoke(this);
methodSetThumbPosition.invoke(this, checked ? 1 : 0);
}
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
对于proguard用户的注意事项:
由于此方法使用反射,因此可能需要额外的proguard规则(如果尚未存在).
-keep class android.support.v7.widget.SwitchCompat {
private void cancelPositionAnimator();
private void setThumbPosition(float);
}
Run Code Online (Sandbox Code Playgroud)
当您使用以下proguard规则之一(或类似规则)时,不需要此附加规则:
-keep class android.support.v7.widget.** { *; }
-keep class android.support.v7.** { *; }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9391 次 |
| 最近记录: |