问题描述
我正在尝试在带有cardviews片段的回收者视图到仅包含1张卡片的片段之间创建过渡。问题在于后退过渡不起作用,而回车过渡则起作用。如果删除setReorderingallowed(true);
,则向后过渡有效,但enter过渡停止工作。
这就是我所拥有的。
带有回收站视图和卡片视图的片段
public class OrdersFragment extends Fragment implements OrderAdapter.OnorderListener {
private OrderAdapter mAdapter;
private TextView bonnenTextView;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
postponeEnterTransition();
}
public View onCreateView(@NonNull LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_bonnen,container,false);
bonnenTextView = view.findViewById(R.id.bonnen_text_view);
RecyclerView orderRecyclerView = view.findViewById(R.id.order_recycler_view);
RecyclerView.LayoutManager layoutManager = new linearlayoutmanager(getContext());
orderRecyclerView.setLayoutManager(layoutManager);
if (mAdapter == null) {
mAdapter = new OrderAdapter(this);
fetchOrders();
}
orderRecyclerView.setAdapter(mAdapter);
return view;
}
private void fetchOrders() {
new OrderFetcher().fetch(new Callback() {
@Override
public void onComplete(Result result) {
if (result instanceof Result.Success) {
mAdapter.setorders((Order[]) ((Result.Success<?>)result).data);
mAdapter.notifyDataSetChanged();
} else {
Toast.makeText(getContext(),"Could not load orders",Toast.LENGTH_SHORT).show();
}
startPostponedEnterTransition();
}
});
}
@Override
public void onorderClick(int position,View view,Order order) {
Log.i("OrderClick","Transition name " + view.getTransitionName());
View carrierTextView = view.findViewById(R.id.carrier_text_view);
View numberTextView = view.findViewById(R.id.id_text_view);
View pickerTextView = view.findViewById(R.id.picker_text_view);
View locationTextView = view.findViewById(R.id.location_text_view);
FragmentTransaction transaction = getParentFragmentManager().beginTransaction();
transaction.addSharedElement(view,view.getTransitionName());
transaction.addSharedElement(carrierTextView,carrierTextView.getTransitionName());
transaction.addSharedElement(numberTextView,numberTextView.getTransitionName());
transaction.addSharedElement(pickerTextView,pickerTextView.getTransitionName());
transaction.addSharedElement(locationTextView,locationTextView.getTransitionName());
transaction.addSharedElement(bonnenTextView,bonnenTextView.getTransitionName());
transaction.replace(R.id.nav_host_fragment,BonFragment.newInstance(view.getTransitionName(),order));
transaction.addToBackStack(null);
transaction.setReorderingallowed(true);
transaction.commit();
}
}
上面带有片段的XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.orders.OrdersFragment">
<TextView
android:id="@+id/bonnen_text_view"
android:transitionName="bonnen_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:text="@string/orders"
android:textColor="@color/secondary"
android:textSize="40sp"
android:textStyle="bold"
android:typeface="normal" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/order_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="20dp"/>
</LinearLayout>
具有单张卡片视图的片段
public static BonFragment newInstance(String cardTransitionName,Order order) {
BonFragment bonFragment = new BonFragment();
Bundle args = new Bundle();
args.putParcelable("orderParcel",order);
args.putString("cardTransitionName",cardTransitionName);
bonFragment.setArguments(args);
return bonFragment;
}
@Override
public View onCreateView(LayoutInflater inflater,Bundle savedInstanceState) {
final View root = inflater.inflate(R.layout.fragment_bon,false);
CardView orderCard = root.findViewById(R.id.order_card);
TextView carrierTextView = root.findViewById(R.id.carrier_text_view);
TextView numberTextView = root.findViewById(R.id.id_text_view);
TextView pickerTextView = root.findViewById(R.id.picker_text_view);
TextView locationTextView = root.findViewById(R.id.location_text_view);
if (getArguments() != null && getArguments().getParcelable("orderParcel") != null) {
Order order = getArguments().getParcelable("orderParcel");
orderCard.setTransitionName(getArguments().getString("cardTransitionName"));
if (order != null) {
carrierTextView.setTransitionName("carrier" + order.getIndex());
carrierTextView.setText(order.getCarrier());
numberTextView.setTransitionName("number" + order.getIndex());
numberTextView.setText(String.valueOf(order.getNumber()));
pickerTextView.setTransitionName("picker" + order.getIndex());
pickerTextView.setText(order.getPicker());
locationTextView.setTransitionName("location" + order.getIndex());
locationTextView.setText(order.getPosition());
carrierTextView.setText("Lorem Ipsum");
numberTextView.setText("Dolor sit amet");
pickerTextView.setText("consectetur adipiscing elit");
locationTextView.setText("Mauris semper");
}
}
orderCard.setonClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getParentFragmentManager().popBackStack();
}
});
Transition transition = TransitionInflater.from(getContext()).inflateTransition(R.transition.card_transition);
setSharedElementEnterTransition(transition);
setSharedElementReturnTransition(transition);
return root;
}
上面带有片段的XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.orders.OrdersFragment">
<TextView
android:transitionName="bonnen_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:text="@string/orders"
android:textColor="@color/secondary"
android:textSize="40sp"
android:textStyle="bold"
android:typeface="normal" />
<androidx.cardview.widget.CardView
android:id="@+id/order_card"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardBackgroundColor="@color/primaryLight"
android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"
android:layout_margin="25dp">
<LinearLayout
android:transitionName="order_card_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="10dp">
<TextView
android:id="@+id/carrier_text_view"
android:transitionName="carrier_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/secondary"
android:textSize="20sp"
android:textStyle="bold"/>
<TextView
android:id="@+id/id_text_view"
android:transitionName="id_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/secondary" />
<TextView
android:id="@+id/picker_text_view"
android:transitionName="picker_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/secondary" />
<TextView
android:id="@+id/location_text_view"
android:transitionName="location_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/secondary" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
这就是setReorderingallowed(true);
这是没有setReorderingallowed(true);
编辑
应用ianhanniballake给出的答案后,我开始使用它。
这是我所做的工作,以供将来参考。
我所做的唯一更改是在OrdersFragment
类中。
我删除了onCreate()
方法的替代。
我从startPostponedEnterTransition();
方法中删除了fetchOrders()
,并添加了
@Override
public void onViewCreated(@NonNull View view,@Nullable Bundle savedInstanceState) {
postponeEnterTransition();
final ViewGroup parentView = (ViewGroup) view.getParent();
parentView.getViewTreeObserver()
.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
parentView.getViewTreeObserver().removeOnPreDrawListener(this);
startPostponedEnterTransition();
return true;
}
});
super.onViewCreated(view,savedInstanceState);
}
就这样
解决方法
根据Use shared element transitions with a RecyclerView
guide,您调用startPostponedEnterTransition()
的时间过早-设置数据后(并调用notifyDataSetChanged()
通知适配器),您需要等到{{ 1}}是实际测量和布局的。这就要求您添加一个RecyclerView
,并且仅在触发后调用OnPreDrawListener
。