共享元素输入转换不起作用,但返回转换正常(片段转换)

时间:2016-09-20 15:12:47

标签: android xamarin.android android-animation android-transitions shared-element-transition

我将从一个显示正在发生的事情的gif开始。

gif of what is happening

列表项应该设置为标题项的动画。如您所见,当按下后退按钮时,标题项会向下设置动画以成为列表项。还有另一个问题,即这些片段的Activity父级也会在淡入淡出过渡后闪现,所以如果您对此有任何想法,我想知道:)

现在,在粘贴代码段之前,先解释一下我的代码。此应用程序导航HTML文档的树结构。小RecyclerView个列表项是文档的标题。单击文档时,它会将标题固定在顶部,并显示一个显示HTML的WebView。只有一个片段,当创建新片段时,该片段会创建自己的另一个实例。结构有点奇怪,但后退按钮和堆栈似乎应该工作。这段代码在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>

这是片段的主要布局。 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"/>

这是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);
        }
    }
}

RecyclerViewAdapater。在这里,我为每个项目设置了TransitionName。我已经检查过以确保转换名称在启动片段时匹配,并且在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;
        }

这是整个OnCreateView方法,可以很好地衡量。但我认为与我的过渡相关的唯一部分是

        _selectedTitleView.TransitionName = "preview" + _selectedTitle;
        _selectedTitleView.Text = _selectedTitle;

_selectedTitleView是固定在顶部的TextView_selectedTitle作为所选RecyclerView项的标题传递给片段。 _topLevelbool,当从自身创建此片段时,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); } } 。这是因为此片段的第一个实例顶部没有锚定文件,因此这些视图不可见。

public class PreviewTransition : TransitionSet
{
    public PreviewTransition()
    {
        SetOrdering(TransitionOrdering.Together);
        AddTransition(new ChangeTransform()).
            AddTransition(new ChangeBounds());
    }
}

这是单击列表项时执行的代码。

SubRoutineSelected

最后,这是动画的类。非常简单。

所以我希望SOMEBODY知道要查看的方向。我真的无法弄清楚为什么返回动画会起作用而不是开始动画。

只是为了澄清,这是两个不同片段之间的过渡。 OnCreateView方法可被视为&#34; First Fragment&#34;,然后var socks = require('socksv5'), SSHClient = require('ssh2').Client; socks.connect({ host: 'ssh.example.org', // destination port: 22, proxyHost: '127.0.0.1', proxyPort: 1080, auths: [ socks.auth.None() ] }, function(socket) { var conn = new SSHClient(); conn.on('ready', function() { conn.exec('uptime', function(err, stream) { if (err) throw err; stream.on('close', function(code, signal) { conn.end(); }).on('data', function(data) { console.log('STDOUT: ' + data); }).stderr.on('data', function(data) { console.log('STDERR: ' + data); }); }); }).connect({ sock: socket, username: 'frylock', privateKey: require('fs').readFileSync('/here/is/my/key') }); }); 是&#34; Second Fragment&#34;。

0 个答案:

没有答案