and*_*per 25 android android-listview rippledrawable android-5.0-lollipop
我希望为Android Lollipop及更高版本的listView项添加一个简单的涟漪效果.
首先,我想将它设置为简单的行,然后设置为9个补丁行甚至是CardView.
我确信这个会很容易,因为它甚至不需要我定义普通选择器.即使对于简单的行,我也没有这样做.出于某种原因,涟漪效应超出了行的边界:

不仅如此,在某些情况下,物品的背景会卡在我设定的颜色上.
这就是我尝试过的:
MainActivity.java
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ListView listView = (ListView) findViewById(android.R.id.list);
final LayoutInflater inflater = LayoutInflater.from(this);
listView.setAdapter(new BaseAdapter() {
@Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
View rootView = convertView;
if (rootView == null) {
rootView = inflater.inflate(android.R.layout.simple_list_item_1, parent, false);
((TextView) rootView.findViewById(android.R.id.text1)).setText("Test");
}
return rootView;
}
@Override
public long getItemId(final int position) {
return 0;
}
@Override
public Object getItem(final int position) {
return null;
}
@Override
public int getCount() {
return 2;
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
activity_main.xml中
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:cacheColorHint="@android:color/transparent"
android:divider="@null"
android:dividerHeight="0px"
android:fadeScrollbars="false"
android:fastScrollEnabled="true"
android:listSelector="@drawable/listview_selector"
android:scrollingCache="false"
android:verticalScrollbarPosition="right" />
Run Code Online (Sandbox Code Playgroud)
res/drawable-v21/listview_selector.xml(我有其他Android版本的普通选择器)
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android" />
Run Code Online (Sandbox Code Playgroud)
除了上面的简单代码,我还尝试为每个项目的background属性设置选择器,而不是在ListView上使用"listSelector",但它没有帮助.
我尝试过的另一件事是设置项目的前景,但它也有相同的结果.
我该如何解决这个问题?它为什么会发生?我做错了什么?
我该如何进一步支持9-patch甚至CardView?
另外,如何设置新背景的状态,例如选中/选中?
更新:使用以下内容修复视图外部的绘图:
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight" >
<item android:id="@android:id/mask">
<color android:color="@color/listview_pressed" />
</item>
</ripple>
Run Code Online (Sandbox Code Playgroud)
但是,它存在背景卡住的问题,我无法找到如何处理剩余的缺失功能(9-patch,cardView,...).
我认为色彩卡住与使用它作为视图的前景有关.
编辑:我看到有些人不明白这里的问题是什么.
这是关于处理新的涟漪效果,同时仍然使用旧的选择器/ CardView.
例如,这是一个选择器 - drawble:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="..." android:state_selected="true"/>
<item android:drawable="..." android:state_activated="true"/>
<item android:drawable="..." android:state_focused="true" android:state_pressed="true"/>
<item android:drawable="..." android:state_pressed="true"/>
<item android:drawable="..."/>
</selector>
Run Code Online (Sandbox Code Playgroud)
这可以用作列表选择器或单个视图的背景.
但是,我找不到如何使用它与波纹drawable一起使用.
我知道涟漪已经处理了一些状态,但对于一些状态,它没有.另外,我无法找到如何使其处理9-patch和CardView.
我希望现在更容易理解我的问题.
关于波纹颜色的问题被"卡住",我认为这是因为我如何制作布局.我想要一个可以检查的布局(当我决定)并且还具有点击的效果,所以这就是我所做的(基于这个网站和另一个我找不到的):
public class CheckableRelativeLayout extends RelativeLayout implements Checkable {
private boolean mChecked;
private static final String TAG = CheckableRelativeLayout.class.getCanonicalName();
private static final int[] CHECKED_STATE_SET = { android.R.attr.state_checked };
private Drawable mForegroundDrawable;
public CheckableRelativeLayout(final Context context) {
this(context, null, 0);
}
public CheckableRelativeLayout(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
public CheckableRelativeLayout(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CheckableRelativeLayout, defStyle,
0);
setForeground(a.getDrawable(R.styleable.CheckableRelativeLayout_foreground));
a.recycle();
}
public void setForeground(final Drawable drawable) {
this.mForegroundDrawable = drawable;
}
public Drawable getForeground() {
return this.mForegroundDrawable;
}
@Override
protected int[] onCreateDrawableState(final int extraSpace) {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
if (isChecked()) {
mergeDrawableStates(drawableState, CHECKED_STATE_SET);
}
return drawableState;
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
final Drawable drawable = getBackground();
boolean needRedraw = false;
final int[] myDrawableState = getDrawableState();
if (drawable != null) {
drawable.setState(myDrawableState);
needRedraw = true;
}
if (mForegroundDrawable != null) {
mForegroundDrawable.setState(myDrawableState);
needRedraw = true;
}
if (needRedraw)
invalidate();
}
@Override
protected void onSizeChanged(final int width, final int height, final int oldwidth, final int oldheight) {
super.onSizeChanged(width, height, oldwidth, oldheight);
if (mForegroundDrawable != null)
mForegroundDrawable.setBounds(0, 0, width, height);
}
@Override
protected void dispatchDraw(final Canvas canvas) {
super.dispatchDraw(canvas);
if (mForegroundDrawable != null)
mForegroundDrawable.draw(canvas);
}
@Override
public boolean isChecked() {
return mChecked;
}
@Override
public void setChecked(final boolean checked) {
setChecked(checked, true);
}
public void setChecked(final boolean checked, final boolean alsoRecursively) {
mChecked = checked;
refreshDrawableState();
if (alsoRecursively)
ViewUtil.setCheckedRecursively(this, checked);
}
@Override
public void toggle() {
setChecked(!mChecked);
}
@Override
public Parcelable onSaveInstanceState() {
// Force our ancestor class to save its state
final Parcelable superState = super.onSaveInstanceState();
final SavedState savedState = new SavedState(superState);
savedState.checked = isChecked();
return savedState;
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public void drawableHotspotChanged(final float x, final float y) {
super.drawableHotspotChanged(x, y);
if (mForegroundDrawable != null) {
mForegroundDrawable.setHotspot(x, y);
}
}
@Override
public void onRestoreInstanceState(final Parcelable state) {
final SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
setChecked(savedState.checked);
requestLayout();
}
// /////////////
// SavedState //
// /////////////
private static class SavedState extends BaseSavedState {
boolean checked;
SavedState(final Parcelable superState) {
super(superState);
}
private SavedState(final Parcel in) {
super(in);
checked = (Boolean) in.readValue(null);
}
@Override
public void writeToParcel(final Parcel out, final int flags) {
super.writeToParcel(out, flags);
out.writeValue(checked);
}
@Override
public String toString() {
return TAG + ".SavedState{" + Integer.toHexString(System.identityHashCode(this)) + " checked=" + checked
+ "}";
}
@SuppressWarnings("unused")
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
@Override
public SavedState createFromParcel(final Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(final int size) {
return new SavedState[size];
}
};
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:修复是添加我做的布局的下一行:
@SuppressLint("ClickableViewAccessibility")
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean onTouchEvent(final MotionEvent e) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && //
e.getActionMasked() == MotionEvent.ACTION_DOWN && //
mForeground != null)
mForeground.setHotspot(e.getX(), e.getY());
return super.onTouchEvent(e);
}
Run Code Online (Sandbox Code Playgroud)
era*_*tin 20
RippleDrawable延伸LayerDrawable.触摸反馈drawable可能包含多个子图层,包括未绘制到屏幕的特殊遮罩层.通过将其android:id值指定为单个层,可以将其设置为掩码mask.第二层可以StateListDrawable.
例如,这是我们的StateListDrawable资源名称item_selectable.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="..." android:state_selected="true"/>
<item android:drawable="..." android:state_activated="true"/>
<item android:drawable="..." android:state_focused="true" android:state_pressed="true"/>
<item android:drawable="..." android:state_pressed="true"/>
<item android:drawable="..."/>
</selector>
Run Code Online (Sandbox Code Playgroud)
为了实现连接选择器的连锁效果,我们可以将上面的drawable设置为RippleDrawable具有名称的图层list_selector_ripple.xml:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/colorControlHighlight">
<item android:id="@android:id/mask">
<color android:color="@android:color/white"/>
</item>
<item android:drawable="@drawable/item_selectable"/>
</ripple>
Run Code Online (Sandbox Code Playgroud)
UPD:
1)使用这个drawable,CardView只需将其设置为android:foreground,如下所示:
<android.support.v7.widget.CardView
...
android:foreground="@drawable/list_selector_ripple"
/>
Run Code Online (Sandbox Code Playgroud)
2)为了使波纹效果在9-patch的范围内起作用,我们应该将这个9-patch drawable设置为ripple drawable(list_selector_ripple_nine_patch.xml)的掩码:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/colorControlHighlight">
<item android:id="@android:id/mask" android:drawable="@drawable/your_nine_patch" />
<item android:drawable="@drawable/your_nine_patch" />
</ripple>
Run Code Online (Sandbox Code Playgroud)
然后设置视图的背景:
<LinearLayout
...
android:background="@drawable/list_selector_ripple_nine_patch"
/>
Run Code Online (Sandbox Code Playgroud)
创建纹波的简单方法是在drawable-v21文件夹中创建一个xml,并将此代码用于xml.
android:backgroung="@drawable/ripple_xyz"
Run Code Online (Sandbox Code Playgroud)
如果,通过java /动态使用.
View.setBackgroundResource(R.drawable.ripple_xyz);
Run Code Online (Sandbox Code Playgroud)
这是ripple_xyz.xml.
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#228B22" >
// ^ THIS IS THE COLOR FOR RIPPLE
<item>
<shape
android:shape="rectangle"
android:useLevel="false" >
<solid android:color="#CCFFFFFF" />
// ^ THIS IS THE COLOR FOR BACK GROUND
</shape>
</item>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6639 次 |
| 最近记录: |