Android:带片段的共享元素过渡
Android: Shared Element Transition with Fragments
我正在做一个项目,我需要使用共享元素在片段之间进行转换。我几乎尝试了所有方法,但过渡效果不起作用。
我有一个名为 TimelineActivity 的 activity,我有 2 个片段,一个动态添加到 TimelineActivity 的 ListFragment 和一个 DetailFragment。
每当我在 ListFragment 的 ListView 中单击一个项目时,该片段就会被 DetailFragment 替换。
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
DetailFragment fragment = DetailFragment.newInstance();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
fragment.setSharedElementEnterTransition(new ChangeBounds().setDuration(2000));
fragment.setEnterTransition(new ChangeBounds().setDuration(2000));
setExitTransition(new ChangeBounds().setDuration(2000));
fragment.setSharedElementReturnTransition(new ChangeBounds().setDuration(2000));
}
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
fragment.setAllowEnterTransitionOverlap(true);
fragment.setAllowReturnTransitionOverlap(true);
ft.replace(R.id.timeline_container, fragment);
ft.addSharedElement(view.findViewById(R.id.transition), "selectClientTransition");
ft.addToBackStack(null);
// Start the animated transition.
ft.commit();
}
在我的 listview_row.xml 列表视图布局中:
<LinearLayout
android:id="@+id/transition"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFF"
android:orientation="vertical"
android:padding="10dp"
android:transitionName="selectClientTransition">
</LinearLayout>
在我的 fragment_detail.xml 中,我有以下内容:
<LinearLayout
android:id="@+id/transition"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFF"
android:orientation="vertical"
android:padding="10dp"
android:transitionName="selectClientTransition"
android:weightSum="12">
</LinearLayout>
我将其添加到我的 AppTheme
<item name="android:windowContentTransitions">true</item>
需要说明的是,片段已被替换,效果很好,但没有 changebounds 效果。我真的被困在这里所以欢迎任何事情。
提前致谢
我刚刚发现只有当我使用其中包含超过 1 个元素的自定义数组适配器时才会发生这种情况,如果我为我的 ListView 切换到普通字符串数组,一切正常,如果我只有 1 个元素也是如此在我的带有自定义数组适配器的列表视图中,一切正常。
您需要为列表中的每个元素设置唯一的转换名称。这是一个例子:
在适配器的 getView 方法中设置转换名称:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// your code...
sharedView.setTransitionName("transition_name_" + position);
}
在 onItemClick 方法中将转换名称发送到 DetailFragment:
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
DetailFragment fragment = DetailFragment.newInstance();
View sharedView = v.findViewById(R.id.shared_view);
Bundle arguments = new Bundle();
arguments.putString(DetailFragment.TRANSITION_NAME, sharedView.getTransitionName());
fragment.setArguments(arguments);
// the rest of your code (replacing fragments, etc)...
}
在 DetailFragment 的 onCreateView 方法中将转换名称设置为视图:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// your code...
View sharedView = inflatedLayout.findViewById(R.id.shared_view);
sharedView.setTransitionName(getArguments().getString(TRANSITION_NAME))
}
我正在做一个项目,我需要使用共享元素在片段之间进行转换。我几乎尝试了所有方法,但过渡效果不起作用。
我有一个名为 TimelineActivity 的 activity,我有 2 个片段,一个动态添加到 TimelineActivity 的 ListFragment 和一个 DetailFragment。
每当我在 ListFragment 的 ListView 中单击一个项目时,该片段就会被 DetailFragment 替换。
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
DetailFragment fragment = DetailFragment.newInstance();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
fragment.setSharedElementEnterTransition(new ChangeBounds().setDuration(2000));
fragment.setEnterTransition(new ChangeBounds().setDuration(2000));
setExitTransition(new ChangeBounds().setDuration(2000));
fragment.setSharedElementReturnTransition(new ChangeBounds().setDuration(2000));
}
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
fragment.setAllowEnterTransitionOverlap(true);
fragment.setAllowReturnTransitionOverlap(true);
ft.replace(R.id.timeline_container, fragment);
ft.addSharedElement(view.findViewById(R.id.transition), "selectClientTransition");
ft.addToBackStack(null);
// Start the animated transition.
ft.commit();
}
在我的 listview_row.xml 列表视图布局中:
<LinearLayout
android:id="@+id/transition"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFF"
android:orientation="vertical"
android:padding="10dp"
android:transitionName="selectClientTransition">
</LinearLayout>
在我的 fragment_detail.xml 中,我有以下内容:
<LinearLayout
android:id="@+id/transition"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFF"
android:orientation="vertical"
android:padding="10dp"
android:transitionName="selectClientTransition"
android:weightSum="12">
</LinearLayout>
我将其添加到我的 AppTheme
<item name="android:windowContentTransitions">true</item>
需要说明的是,片段已被替换,效果很好,但没有 changebounds 效果。我真的被困在这里所以欢迎任何事情。
提前致谢
我刚刚发现只有当我使用其中包含超过 1 个元素的自定义数组适配器时才会发生这种情况,如果我为我的 ListView 切换到普通字符串数组,一切正常,如果我只有 1 个元素也是如此在我的带有自定义数组适配器的列表视图中,一切正常。
您需要为列表中的每个元素设置唯一的转换名称。这是一个例子:
在适配器的 getView 方法中设置转换名称:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// your code...
sharedView.setTransitionName("transition_name_" + position);
}
在 onItemClick 方法中将转换名称发送到 DetailFragment:
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
DetailFragment fragment = DetailFragment.newInstance();
View sharedView = v.findViewById(R.id.shared_view);
Bundle arguments = new Bundle();
arguments.putString(DetailFragment.TRANSITION_NAME, sharedView.getTransitionName());
fragment.setArguments(arguments);
// the rest of your code (replacing fragments, etc)...
}
在 DetailFragment 的 onCreateView 方法中将转换名称设置为视图:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// your code...
View sharedView = inflatedLayout.findViewById(R.id.shared_view);
sharedView.setTransitionName(getArguments().getString(TRANSITION_NAME))
}