recyclerview 中的触摸没有涟漪效应
Posted
技术标签:
【中文标题】recyclerview 中的触摸没有涟漪效应【英文标题】:No ripple effect on touch in recyclerview 【发布时间】:2015-11-07 00:24:25 【问题描述】:我有一个带有四个网格元素 (2*2) 的 recyclerview,它们像菜单一样工作。但是,当我单击它们时,不会显示涟漪效应。它只是将我带到下一个活动,而没有任何视觉确认视图被按下。有人可以帮忙吗?
主活动
public class MainActivity extends AppCompatActivity implements MainMenuAdapter.OnItemClickListener
Toolbar toolbar;
private static List<ViewModel> tileItems = new ArrayList<>();
static
tileItems.add(new ViewModel("Activity", "#3F51B5", R.drawable.activity));
tileItems.add(new ViewModel("Profile", "#E91E63", R.drawable.profile));
tileItems.add(new ViewModel("Training", "#FF5722", R.drawable.training));
tileItems.add(new ViewModel("Diet", "#4CAF50", R.drawable.diet));
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new GridLayoutManager(this, 2));
MainAdapter adapter = new MainAdapter(tileItems, MainActivity.this);
recyclerView.setAdapter(adapter);
adapter.setOnItemClickListener(this);
// Toolbar
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
@Override
public void onBackPressed()
this.moveTaskToBack(true);
// this.finishAffinity();
@Override
public boolean onCreateOptionsMenu(Menu menu)
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
@Override public void onItemClick(View view, ViewModel viewModel)
主适配器
public class MainAdapter extends RecyclerView.Adapter<MainMenuAdapter.ViewHolder> implements View.OnClickListener
private List<ViewModel> items;
private OnItemClickListener onItemClickListener;
private Context context;
// Adapter constructor
public MainAdapter(List<ViewModel> items, Context context)
this.items = items;
this.context = context;
public void setOnItemClickListener(OnItemClickListener onItemClickListener)
this.onItemClickListener = onItemClickListener;
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.main_item, parent, false);
return new ViewHolder(v);
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position)
final ViewModel dataItem = items.get(position);
viewHolder.colorBlock.setBackgroundColor(dataItem.getColor());
viewHolder.menuName.setText(dataItem.getName());
viewHolder.menuIcon.setImageResource(dataItem.getImage());
viewHolder.itemView.setTag(dataItem);
if (dataItem.getActivity() != null)
viewHolder.colorBlock.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
Intent i = new Intent(context, dataItem.getActivity());
context.startActivity(i);
);
@Override
public int getItemCount()
return items.size();
@Override public void onClick(final View v)
// Give some time to the ripple to finish the effect
if (onItemClickListener != null)
new Handler().postDelayed(new Runnable()
@Override public void run()
onItemClickListener.onItemClick(v, (ViewModel) v.getTag());
, 200);
/** This is our ViewHolder class */
public static class ViewHolder extends RecyclerView.ViewHolder
public TextView menuName;
public View colorBlock;
public ImageView menuIcon;
public ViewHolder(View convertView)
super(convertView); // Must call super() first
menuName = (TextView) convertView.findViewById(R.id.menuName);
colorBlock = (View) convertView.findViewById(R.id.colorBlock);
menuIcon = (ImageView) convertView.findViewById(R.id.menuItem);
public interface OnItemClickListener
void onItemClick(View view, ViewModel viewModel);
activity_main.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
tools:context=".MainActivity">
<include
android:id="@+id/toolbar"
layout="@layout/toolbar"
android:layout_
android:layout_/>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_below="@id/toolbar"
android:layout_width= "match_parent"
android:layout_height = "match_parent" />
</RelativeLayout>
main_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground">
<View
android:id="@+id/colorBlock"
android:layout_
android:layout_ />
<ImageView
android:id="@+id/menuItem"
android:layout_
android:layout_
android:layout_centerHorizontal="true"
android:padding="16dp"
/>
<TextView
android:id="@+id/menuName"
android:layout_
android:layout_
android:padding="16dp"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:textColor="@android:color/white"
android:textSize="16sp"/>
</RelativeLayout>
【问题讨论】:
涟漪不会自动发生,它只是一个可绘制的,你必须自己去把它放在某个视图中。 developer.android.com/reference/android/graphics/drawable/… 【参考方案1】:如果你将 main_item.xml 的背景设置为?android:selectableItemBackground
或?selectableItemBackground
,就会出现涟漪效应(@Budius 在他的评论中是错误的)。我找到了对第二个的参考。然而,AndroidStudio 警告说它在 com.android.support:design 中是私有的。尝试使用该私有版本时,我的应用程序崩溃了。我猜第一个带有“android:”前缀,瞧,它有效。
也许您是无意中设置了android:foreground
?我试过了,但我的 RecyclerView 项目没有任何反应。
您更新后的 RelativeLayout 将是:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
android:background="?android:selectableItemBackground">
我还看到android:background="?android:attr/selectableItemBackground"
启动了涟漪效应。我还要提到 selectableItemBackground 不需要位于 main_item.xml 的根元素上。我在根项中使用背景颜色,然后在嵌套的 ViewGroup 上设置 selectableItemBackground。
我的答案来自不使用材料设计 appcompat 的参考框架。如果您使用的是材料设计 appcompat 支持库,我怀疑会有所不同。
【讨论】:
以上是关于recyclerview 中的触摸没有涟漪效应的主要内容,如果未能解决你的问题,请参考以下文章
Android L 的涟漪效应 - 按钮的触摸反馈 - 使用 XML