Jas*_*oms 5 android android-animation xamarin.android android-transitions shared-element-transition
我将从显示事件情况的gif图像开始。
该列表项应该设置为动画头文件。如您所见,当按下“后退”按钮时,标题项目会向下动画,成为列表项目。还有一个问题,这些片段的“活动”父对象也会在渐变过渡之后闪烁,因此,如果您对此有任何想法,我想知道:)
现在,在粘贴代码片段之前对我的代码进行一些解释。这个应用程式可浏览HTML文件的树状结构。小RecyclerView列表项是文档的标题。单击文档时,它会将标题固定在顶部,WebView并显示HTML。只有一个片段,并且在创建新片段时,该片段会创建其自身的另一个实例。该结构有些奇怪,但是后退按钮和堆栈似乎可以正常工作。这段代码在C#中,因为我使用的是Xamarin.Android,但除单击处理外,大多数代码都非常相似。
我可以从我的XML文件开始。布局仍然是WIP,所以我知道它们很凌乱。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/linear_layout_main"
android:background="#ffffff">
<LinearLayout
android:id="@+id/progressLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone"
android:gravity="center">
<ProgressBar
android:id="@+id/progressbar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:id="@+id/subroutines_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:background="#ffffff">
<TextView
android:id="@+id/routine_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:padding="5dp"
android:textSize="24sp"
android:visibility="gone"/>
<FrameLayout
android:id="@+id/preview_frame"
android:layout_width ="match_parent"
android:layout_height="150dp"
android:visibility="gone">
<WebView
android:id="@+id/routine_preview"
android:layout_width="match_parent"
android:layout_height="150dp"
android:gravity="center_vertical"
android:padding="5dp"
android:transitionName="webview_preview_transition"
android:scrollbars="none"
android:visibility="gone"/>
<TextView
android:id="@+id/routine_preview_clickable"
android:layout_width="match_parent"
android:layout_height="150dp"
android:gravity="center_vertical"
android:visibility="gone"/>
</FrameLayout>
<TextView
android:id="@+id/preview_separator"
android:layout_width="match_parent"
android:layout_height="1dp"
android:gravity="center_vertical"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:background="@color/material_grey_100"
android:visibility="gone"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/routines_rv"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</android.support.v7.widget.RecyclerView>
</LinearLayout>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
这是片段的主要布局。该WebView是一个框架,由一个看不见的覆盖内TextView,因为我需要能够点击它扩大预览。
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/routines_rv_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:gravity="center_vertical"
android:textSize="16sp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:background="@android:color/transparent"/>
Run Code Online (Sandbox Code Playgroud)
这是RecyclerView列表项。
namespace Routines.Views.Routines
{
class RoutineAdapter : RecyclerViewAdapter<PublishedDocumentFragmentDTO>
{
public RoutineAdapter(List<PublishedDocumentFragmentDTO> items,
int layout,
Func<View, Action<int>, HolderBase> viewHolderInitializer)
: base(items, layout, viewHolderInitializer) { }
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
var vh = (RoutineHolder)holder;
vh.Text.Text = Items[position].Title;
vh.Text.TransitionName = "preview" + Items[position].Title;
}
public void UpdateData(List<PublishedDocumentFragmentDTO> routines)
{
Items = routines;
}
}
public class RoutineHolder : HolderBase
{
public TextView Text { get; private set; }
public RoutineHolder(View itemView, Action<int> action) : base(itemView, action)
{
Text = itemView.FindViewById<TextView>(Resource.Id.routines_rv_item);
}
}
}
Run Code Online (Sandbox Code Playgroud)
的RecyclerViewAdapater。在这里,我TransitionName为每个项目设置。我已经检查过以确保在启动片段和in时过渡名称匹配OnCreateView,因此我认为这不是问题。
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var v = inflater.Inflate(Resource.Layout.routines_rv_fragment, container, false);
_subRoutinesLayout = v.FindViewById<LinearLayout>(Resource.Id.subroutines_layout);
_subRoutinesView = v.FindViewById<RecyclerView>(Resource.Id.routines_rv);
_progressLayout = v.FindViewById<LinearLayout>(Resource.Id.progressLayout);
_selectedTitleView = v.FindViewById<TextView>(Resource.Id.routine_title);
_selectedPreview = v.FindViewById<WebView>(Resource.Id.routine_preview);
_separator = v.FindViewById<TextView>(Resource.Id.preview_separator);
_previewFrame = v.FindViewById<FrameLayout>(Resource.Id.preview_frame);
_selectedPreviewClickable = v.FindViewById<TextView>(Resource.Id.routine_preview_clickable);
_subRoutinesView.HasFixedSize = true;
_subRoutinesView.SetLayoutManager(new LinearLayoutManager(Activity));
_subRoutinesView.AddItemDecoration(new MaterialDesignDivider(Activity, Resource.Drawable.md_divider));
_selectedPreview.TransitionGroup = true;
if (!_topLevel)
{
_selectedTitleView.Visibility = ViewStates.Visible;
_selectedPreview.Visibility = ViewStates.Visible;
_separator.Visibility = ViewStates.Visible;
_previewFrame.Visibility = ViewStates.Visible;
_selectedPreviewClickable.Visibility = ViewStates.Visible;
_selectedTitleView.TransitionName = "preview" + _selectedTitle;
_selectedTitleView.Text = _selectedTitle;
IRoutinesService _routinesService;
var routinesContainer = AutoFac.Container;
_routinesService = routinesContainer.Resolve<IRoutinesService>();
var blobIdGuid = new Guid(_selectedBlobId);
Tuple<bool, string> tuple = _routinesService.GetFragment(blobIdGuid);
if (tuple.Item1)
{
string mimeType = "text/html";
string encoding = "UTF-8";
string html = File.ReadAllText(tuple.Item2);
_selectedPreview.LoadDataWithBaseURL("", transformedHtml, mimeType, encoding, "");
}
_selectedPreviewClickable.Click += PreviewClicked;
}
return v;
}
Run Code Online (Sandbox Code Playgroud)
这是整个OnCreateView方法,很好。但我认为与过渡有关的唯一部分是
_selectedTitleView.TransitionName = "preview" + _selectedTitle;
_selectedTitleView.Text = _selectedTitle;
Run Code Online (Sandbox Code Playgroud)
_selectedTitleView是TextView锚定在顶部的。 _selectedTitle将作为RecyclerView所选项目的标题传递到片段中。 _topLevel是从其自身创建此片段时bool设置的true。这是因为该片段的第一个实例在顶部没有锚定文件,因此这些视图不可见。
private void SubRoutineSelected(int position)
{
PublishedDocumentFragmentDTO selectedRoutine;
IRoutinesService _routinesService;
var container = AutoFac.Container;
_routinesService = container.Resolve<IRoutinesService>();
if (_topLevel)
{
selectedRoutine = _viewModel.SelectedRoutineTree[position];
}
else
{
var childList = _viewModel.RetrieveSelectedChildren(_fragId, _viewModel.SelectedRoutineTree);
selectedRoutine = childList[position];
}
var newFragId = selectedRoutine.FragmentId;
var newBlobId = selectedRoutine.BlobId;
var title = selectedRoutine.Title;
if (selectedRoutine.Children.Any())
{
SubroutinesFragment selectedRoutineFragment = new SubroutinesFragment(_viewModel, newFragId, false, title, newBlobId);
if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
{
SharedElementReturnTransition = new PreviewTransition();
ExitTransition = new Fade();
selectedRoutineFragment.SharedElementEnterTransition = new PreviewTransition();
selectedRoutineFragment.EnterTransition = new Fade();
}
var test = (RoutineHolder)_subRoutinesView.FindViewHolderForAdapterPosition(position);
FragmentManager.BeginTransaction().
Replace(Resource.Id.main_frame, selectedRoutineFragment).
AddToBackStack(null).
AddSharedElement(test.Text, test.Text.TransitionName).
Commit();
}
else
{
var intent = new Intent(Activity, typeof(RoutineActivity));
intent.PutExtra(RoutineBundleKeys.BLOB_ID, newBlobId);
intent.PutExtra(RoutineBundleKeys.ROUTINE_TITLE, title);
StartActivity(intent);
}
}
Run Code Online (Sandbox Code Playgroud)
这是单击列表项时执行的代码。
public class PreviewTransition : TransitionSet
{
public PreviewTransition()
{
SetOrdering(TransitionOrdering.Together);
AddTransition(new ChangeTransform()).
AddTransition(new ChangeBounds());
}
}
Run Code Online (Sandbox Code Playgroud)
最后,这是动画的类。很简单的。
因此,我希望SOMEBODY知道应朝哪个方向发展。我真的无法弄清楚为什么返回动画有效,但不能弄清楚起始动画为何。
为了澄清,这是两个不同片段之间的过渡。该SubRoutineSelected方法可以被认为是“第一个片段”,然后OnCreateView是“第二个片段”。
| 归档时间: |
|
| 查看次数: |
714 次 |
| 最近记录: |