J'ai un RecyclerView
avec un GridLayoutManager
avec spanCount=2
et une orientation Vertical
.
Mes articles sont correctement affichés comme l'image ci-dessous:
Maintenant, je dois ajouter une animation qui dit qu’un clic sur l’un des éléments, par exemple le numéro "3", augmente sa largeur et que l’élément à côté (dans cet exemple, le nombre "4") se trouve en dehors du parent. /écran.
Visuellement, ce serait quelque chose comme ça:
Pour développer l'élément, je règle la visibilité sur VISIBLE
en vue à l'intérieur de l'élément et pour le réduire, définissez la visibilité sur GONE
.
Pour le moment, je peux afficher et masquer cette vue, mais cela ne prend que l'espace de l'élément, cela augmente la largeur en poussant l'élément à côté.
Donc mes questions sont:
Il est possible d'utiliser GridLayoutManager
comme suit:
GridLayoutManager
avec deux étendues.VISIBLE
et GONE
.VISIBLE
, augmentez la taille de la itemView
de la largeur de la vue extensible. Traduisez la vue vers la droite en fonction de l’extension pour tenir compte de l’augmentation de la taille de la vue de gauche.Voici un exemple. Je suppose que seule la vue de gauche peut être cliquée. Le processus général est le même pour la vue de droite si vous pouvez également cliquer dessus, mais les détails diffèrent quant à ce qui doit être traduit, etc.
Cet exemple ne conserve pas les informations relatives au statut de la vue impliqué dans une extension. Par conséquent, si vous développez une vue, faites-la défiler vers le bas et la sauvegarder, la vue risque d'être réinitialisée.
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
Cet adaptateur de démonstration suppose qu’il existe un nombre pair d’éléments à afficher. Pour simplifier, les contrôles nuls n'ont pas été codés.
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>
Je vois comment implémenter cela en utilisant HorizontalScrollView/RecyclerView avec LinearLayoutManager. Au lieu d'utiliser GridLayoutManager avec deux colonnes, vous pouvez utiliser LinearLayoutManager avec ces vues:
__|HorizontalScrollView/RecyclerView|
| [Firts view] [Second view] |
|---------------------------------|
Ensuite, il est facile d'implémenter des vues étendues.
Dans d'autres cas, vous aurez besoin d'un gestionnaire de disposition personnalisé, qui peut faire défiler horizontalement et verticalement.