#android #android-fragments #android-recyclerview #android-animation #shared-element-transition
Вопрос:
Я прошел половину Интернета и перепробовал все возможные переходы, и я не могу получить тот же эффект, что whatsapp делает с группой изображений (когда их 4).
Я делаю это с androidx, я не думаю, что в этом проблема.
Что я хочу: пример Whatsapp
То, что я нашел, но не работает для меня, потому что они связаны с деятельностью: Пример деятельности
Мой эффект: Мой эффект не работает
Фрагмент кода:
ФРАГМЕНТ А (щелчок держателя):
// imageView is the view inside of itemView of viewholder in chat, view is the viewholder
private void openMediaListWithTransition(ImageView imageView, int imagePosition, int messagePosition, View view) {
String transitionName = imageView.getTransitionName();
ImageListFragment imageListFragment = ImageListFragment.newInstance(requireContext(),
((ChatAdapter.MessageMultiMedia) adapter.getMessageAt(
messagePosition)).getMessages(), imagePosition, messagePosition, "TRANSITION");
//imageListFragment.setEnterTransition(new Fade());
//imageListFragment.setSharedElementEnterTransition(new DetailsTransition());
//imageListFragment.setEnterTransition(new Fade());
//setExitTransition(new Fade());
//imageListFragment.setSharedElementReturnTransition(new DetailsTransition());
imageView.setTransitionName("TRANSITION");
ViewCompat.setTransitionName(imageView, "TRANSITION");
getParentFragmentManager()
.beginTransaction()
.setReorderingAllowed(true)
.addSharedElement(imageView, "TRANSITION")
.replace(R.id.rlChat, imageListFragment)
.addToBackStack(null)
.commit();
getParentFragmentManager().setFragmentResultListener("XD", getViewLifecycleOwner(), (requestKey, result) -> {
getParentFragmentManager().beginTransaction().remove(imageListFragment).commit();
});
}
Экспликация держателя просмотра ФРАГМЕНТА переработчика A:
Объяснение
ФРАГМЕНТ В:
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
binding = FragmentImagesListBinding.inflate(inflater);
starterPosition = getArguments().getInt(ITEM_POSITION);
messagePosition = getArguments().getInt(MESSAGE_POSITION);
postponeEnterTransition();
prepareRecycler();
}
@SuppressLint("NotifyDataSetChanged")
private void prepareRecycler() {
ImageListAdapter adapter = new ImageListAdapter(messagePosition, this);
adapter.setMessagesList(
GSON.fromJson(getArguments().getString(MESSAGE_LIST),
new TypeToken<List<MessageImpl>>() {
}.getType()));
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
binding.rvChatImagesList.setLayoutManager(linearLayoutManager);
binding.rvChatImagesList.setAdapter(adapter);
binding.draggableFrame.addListener(new ElasticDragDismissListener() {
@Override
public void onDrag(float elasticOffset, float elasticOffsetPixels, float rawOffset, float rawOffsetPixels) {
}
@Override
public void onDragDismissed() {
isReturning = true;
getParentFragmentManager().setFragmentResult("XD", null);
//getParentFragmentManager().beginTransaction().remove(ImageListFragment.this).commit();
}
});
//getParentFragment().startPostponedEnterTransition();
//binding.rvChatImagesList.scrollToPosition(position);
//adapter.notifyDataSetChanged();
//prepareSharedElementTransition();
}
ADAPTER RECYCLER FRAGMENT B:
public class ImageListAdapter extends RecyclerView.Adapter<ImageListAdapter.ViewHolder> {
private List<Message> messages;
private static int messagePosition;
public Fragment fragment;
public ImageListAdapter(int mssagePosition, Fragment fragment) {
ImageListAdapter.messagePosition = messagePosition;
this.fragment = fragment;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new ViewHolder(
ItemImageListBinding.inflate(
LayoutInflater.from(parent.getContext()), parent, false));
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Message message = messages.get(position);
UtilMessages.MediaMessage content = message.getContent(UtilMessages.MediaMessage.class);
FileUtils.Type type = FileUtils.getMimeType(content.url);
holder.bind(position, fragment);
switch (type) {
case IMAGE:
prepareImageHolder(holder, position, content.url);
break;
case VIDEO:
prepareVideoHolder(holder, position, content.url);
break;
case AUDIO:
break;
case CONTACT:
break;
case UNKNOWN:
break;
}
}
private void prepareVideoHolder(ViewHolder holder, int position, String url) {
holder.ibPlayVideo.setVisibility(View.VISIBLE);
Glide.with(holder.itemView).load(new File(url)).into(holder.ivPicture);
}
private void prepareImageHolder(ViewHolder holder, int position, String url) {
holder.ibPlayVideo.setVisibility(View.GONE);
//Glide.with(holder.itemView).load(new File(url)).into(holder.ivPicture);
holder.ivPicture.setImageBitmap(BitmapFactory.decodeFile(url));
//Glide.with(holder.itemView).load(new File(url)).into(holder.ivPicture);
}
@Override
public int getItemCount() {
return messages.size();
}
public void setMessagesList(List<Message> messagesList) {
messages = messagesList;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private final ImageView ivPicture;
private final ImageButton ibPlayVideo;
public ViewHolder(@NonNull ItemImageListBinding binding) {
super(binding.getRoot());
ivPicture = binding.ivImageViewImage;
ibPlayVideo = binding.ibPlayVideo;
}
public void bind(int position, Fragment fragment) {
if (position == messagePosition) {
ivPicture.setTransitionName("TRANSITION");
ViewCompat.setTransitionName(ivPicture, "TRANSITION");
ivPicture.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
ivPicture.getViewTreeObserver().removeOnPreDrawListener(this);
fragment.startPostponedEnterTransition();
return true;
}
});
/*ivPicture.setTransitionName("Image_" position "_" messagePosition);
// ivPicture, "Image_" position "_" messagePosition
ViewCompat.setTransitionName(ivPicture,"Image_" position "_" messagePosition);
ivPicture.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
ivPicture.getViewTreeObserver().removeOnPreDrawListener(this);
fragment.startPostponedEnterTransition();
return true;
}
});*/
}
}
}
Any idea?