我希望为 Android Lollipop 及更高版本的 listView 项目添加一个简单的涟漪效果。
首先我想将它设置为简单的行,然后设置为 9-patch 行,甚至 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;
}
});
}
}
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" />
res/drawable-v21/listview_selector.xml(我有其他安卓版本的普通选择器)
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android" />
除了上面的简单代码之外,我还尝试为每个项目的背景属性设置选择器,而不是在 ListView 上使用“listSelector”,但没有帮助。
我尝试的另一件事是设置项目的前景,但结果也相同。
我该如何解决这个问题?为什么会发生?我做错了什么?
如何更进一步,支持 9-patch 甚至 CardView ?
另外,如何设置新背景的状态,比如被选中/选中?
更新: View 外的绘图已使用以下方法修复:
<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>
仍然存在背景卡住的问题,我找不到如何处理其余缺失的功能(9-patch、cardView、...)。
我认为卡住的颜色与将其用作 View 的前景有关。
编辑:我看到有些人不明白这里的问题是什么。
这是关于处理新的涟漪效应,同时仍然使用旧的选择器/CardView。
例如,这里有一个 selector-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>
这可以用作列表选择器或单个 View 的背景。
但是,我找不到如何将它与可绘制的波纹一起使用。
我知道涟漪已经处理了一些状态,但对于一些状态,它没有。另外,我不知道如何让它处理 9-patch 和 CardView。
我希望现在更容易理解我遇到的问题。
关于波纹颜色“卡住”的问题,我认为是因为我的布局方式。我想要一个可以检查的布局(当我决定时)并且还具有点击的效果,所以这就是我所做的(基于 this website 和另一个我找不到的):
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];
}
};
}
}
编辑:修复是为我所做的布局添加下一行:
@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);
}
最佳答案
RippleDrawable 扩展了 LayerDrawable。触摸反馈可绘制对象可能包含多个子层,包括未绘制到屏幕的特殊 mask 层。通过将其 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>
为了与选择器一起实现波纹效果,我们可以将上面的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>
UPD:
1) 要将这个drawable 与CardView 一起使用,只需将其设置为android:foreground,如下所示:
<android.support.v7.widget.CardView
...
android:foreground="@drawable/list_selector_ripple"
/>
2) 为了使波纹效果在 9-patch 的范围内起作用,我们应该将此 9-patch 可绘制对象设置为波纹可绘制对象的掩码 (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>
然后设置 View 的背景:
<LinearLayout
...
android:background="@drawable/list_selector_ripple_nine_patch"
/>
关于android - 如何处理 9-patch 和 CardView 上的 Ripple 效果,并控制选择器的状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27170922/
当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少
我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.
我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新rubygems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
状态:我正在构建一个应用程序,其中需要一个可供用户选择颜色的字段,该字段将包含RGB颜色代码字符串。我已经测试了一个看起来很漂亮但效果不佳的。它是“挑剔的颜色”,并托管在此存储库中:https://github.com/Astorsoft/picky-color.在这里我打开一个关于它的一些问题的问题。问题:请建议我在Rails3应用程序中使用一些颜色选择器。 最佳答案 也许页面上的列表jQueryUIDevelopment:ColorPicker为您提供开箱即用的产品。原因是jQuery现在包含在Rails3应用程序中,因此使用基
说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路
我有一个.pfx格式的证书,我需要使用ruby提取公共(public)、私有(private)和CA证书。使用shell我可以这样做:#ExtractPublicKey(askforpassword)opensslpkcs12-infile.pfx-outfile_public.pem-clcerts-nokeys#ExtractCertificateAuthorityKey(askforpassword)opensslpkcs12-infile.pfx-outfile_ca.pem-cacerts-nokeys#ExtractPrivateKey(askforpassword)o