我有一个RecyclerView
,一个GridLayoutManager
,一个spanCount=2
,一个Vertical
方向。
我的物品正确显示为下图:
现在,我需要添加一个动画,当单击其中一个项目(例如数字“ 3”)时,该项目会增加其宽度并将其旁边的项目(在本示例中为“ 4”)推到一部分在父级/屏幕之外。
从视觉上看,应该是这样的:
要展开该项目,我要将可见性设置为VISIBLE
,并将其折叠到该项目内部的视图中,请将可见性设置为GONE
。
目前,我可以显示和隐藏该视图,但是它仅占用项目的空间,并且确实增加了将项目推向其旁边的宽度。
所以我的问题是:
答案 0 :(得分:4)
可以按以下方式使用GridLayoutManager
:
GridLayoutManager
。VISIBLE
和GONE
的视图的项目布局。VISIBLE
,将itemView
的大小增加可扩展视图的宽度。通过扩展量将视图向右平移,以适应增加的左视图大小。这里是一个例子。我假设只能单击左视图。如果也可以单击,则正确的视图的一般过程是相同的,但是细节不同,需要翻译的内容等。
此示例未保留扩展所涉及的视图状态信息,因此,如果您扩展视图然后向下滚动并向上备份,则该视图可能会重置。
MainActivity.java
public class MainActivity extends AppCompatActivity {
private LinearLayoutManager mLayoutManager;
private RecyclerViewAdapter mAdapter;
private List<String> mItems = new ArrayList<>();
private RecyclerView mRecycler;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for (int i = 0; i < 100; i++) {
mItems.add(i + 1 + "");
}
mLayoutManager = new GridLayoutManager(this, 2);
mRecycler = findViewById(R.id.recyclerView);
mAdapter = new RecyclerViewAdapter(mItems);
mRecycler.setLayoutManager(mLayoutManager);
mRecycler.setAdapter(mAdapter);
}
}
RecyclerViewAdapter.java
该演示适配器假定要显示的项目数是偶数。为简单起见,未对空检查进行编码。
class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
implements View.OnClickListener {
private final List<String> mItems;
private RecyclerView mRecyclerView;
RecyclerViewAdapter(List<String> items) {
mItems = items;
}
@Override
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
mRecyclerView = recyclerView;
}
@Override
public @NonNull
RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item, parent, false);
return new ItemViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
ItemViewHolder vh = (ItemViewHolder) holder;
vh.mItemTextView.setText(mItems.get(position));
// Only allow clicks on left items which corresponds to even positions.
vh.mItemTextView.setOnClickListener((position % 2 == 0) ? this : null);
// Reset translation and expansion if viewholder is reused.
vh.itemView.setTranslationX(0);
if (vh.mExpansion != 0) {
vh.itemView.getLayoutParams().width -= vh.mExpansion;
vh.mExpansion = 0;
vh.mGoneView.setVisibility(View.GONE);
}
int bgColor = (position % 2 == 0)
? android.R.color.holo_blue_light
: android.R.color.holo_green_light;
vh.mItemTextView.setBackgroundColor(vh.itemView.getContext().getResources().getColor(bgColor));
}
@Override
public int getItemCount() {
return (mItems == null) ? 0 : mItems.size();
}
@Override
public int getItemViewType(int position) {
return TYPE_ITEM;
}
@Override
public void onClick(View v) {
ItemViewHolder vh = (ItemViewHolder) mRecyclerView.findContainingViewHolder(v);
View itemView = vh.itemView;
// Get the child to the right. This child will be translated to the right to make room
// for the expanded left view.
View rightChild = mRecyclerView.getChildAt(findRightChildPos(vh.itemView));
if (vh.mGoneView.getVisibility() == View.GONE) {
// Reveal the "GONE" view, expand the itemView and translate the right-hand view.
vh.mGoneView.setVisibility(View.VISIBLE);
int translation = vh.mGoneView.getLayoutParams().width;
itemView.getLayoutParams().width = itemView.getWidth() + translation;
// Works with "GONE" view of fixed width. Make adjustments if width is variable.
rightChild.setTranslationX(translation);
vh.mExpansion = translation;
} else { // View is expanded.
// Undo the expansion changes.
vh.mGoneView.setVisibility(View.GONE);
itemView.getLayoutParams().width = itemView.getWidth() - vh.mExpansion;
vh.mExpansion = 0;
rightChild.setTranslationX(0);
}
}
// Find the child to the right of a view within the RecyclerView.
private int findRightChildPos(View view) {
for (int i = 0; i < mRecyclerView.getChildCount(); i++) {
if (mRecyclerView.getChildAt(i) == view) {
return i + 1;
}
}
return RecyclerView.NO_POSITION;
}
static class ItemViewHolder extends RecyclerView.ViewHolder {
final TextView mItemTextView;
final View mGoneView;
int mExpansion;
ItemViewHolder(View item) {
super(item);
mItemTextView = item.findViewById(R.id.textView);
mGoneView = item.findViewById(R.id.expandingView);
}
}
private final static int TYPE_ITEM = 1;
}
recycler_item.xml
<LinearLayout
android:id="@+id/item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:clickable="true"
android:orientation="horizontal">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:textSize="48sp"
tools:background="@android:color/holo_blue_light"
tools:text="1" />
<View
android:id="@+id/expandingView"
android:layout_width="100dp"
android:layout_height="match_parent"
android:background="@android:color/holo_purple"
android:visibility="gone" />
<View
android:layout_width="10dp"
android:layout_height="match_parent"
android:background="@android:color/holo_red_light" />
</LinearLayout>
答案 1 :(得分:0)
我看到了如何使用带有LinearLayoutManager的HorizontalScrollView / RecyclerView来实现这一点。可以将LinearLayoutManager与以下视图一起使用,而不是将GridLayoutManager与两列一起使用:
__|HorizontalScrollView/RecyclerView|
| [Firts view] [Second view] |
|---------------------------------|
然后实现扩展视图很简单。
在其他情况下,您将需要自定义布局管理器,该管理器可以水平和垂直滚动。