• Android:安卓学习笔记之共享元素的简单理解和使用


    1 、基本概念

    Andriod 5.0及之后,开始支持共享元素动画,两个Activity或者fragment可以共享某些控件,例如Activity A跳转到Activity B的时候,A的某个控件能自动移动到B的相应控件的位置,产生动画。

    在这里插入图片描述

    2、基本使用

    1、Activity to Activity跳转实现

    1.1、使用步骤

    1、为每个共享元素视图分配一个唯一的过渡名称。

    2、makeSceneTransitionAnimation添加共享元素视图和切换后对应共享元素视图的过渡名称。

    3、 页面跳转。

    1.2、案例说明

    1、第一步,设置ActivityA、ActivityB中view的transitionName属性, 属性值是自定义的,就是一个字符串。

        <?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">
        <ImageView android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@mipmap/timg"
            android:id="@+id/share_pic"
            android:transitionName="@string/share_pic_str"
            android:scaleType="fitXY"/>
    </LinearLayout>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
     <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="match_parent"
        android:layout_height="match_parent">
        <ImageView android:layout_width="50dp"
            android:layout_height="50dp"
            android:src="@mipmap/timg"
            android:id="@+id/share_pic"
            android:transitionName="@string/share_pic_str"
            android:scaleType="fitXY" />
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    也可以手动设置transitionName属性

    ShareAnimatorActivity

    ActivityOptionsCompat activityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(
                        MainActivity.this,
    
                        // Now we provide a list of Pair items which contain the view we can transitioning
                        // from, and the name of the view it is transitioning to, in the launched activity
                        new Pair<>(view.findViewById(R.id.imageview_item),
                                R.string.share_pic_str));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    SecondShareAnimActivity

    ViewCompat.setTransitionName(mImageView, R.string.share_pic_str);
    
    • 1

    2、设置intent跳转

    Intent intent = new Intent(ShareAnimatorActivity.this,SecondShareAnimActivity.class);
    
    Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(ShareAnimatorActivity.this,shareImg,getString(R.string.share_pic_str)).toBundle();
    
    startActivity(intent,bundle);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    makeSceneTransitionAnimation()参数解释:

    • activity就是发起跳转的Activity,
    • shareElement就是共享的控件的id,
    • sharedElementName就是第一步定义的字符串。
    • 这个方式只支持共享单个控件。

    具体如下:发起跳转的Activity:

    public class ShareAnimatorActivity extends AppCompatActivity {
        private ImageView shareImg;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_share_animator_main);
            shareImg = (ImageView) findViewById(R.id.share_pic);
            shareImg.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.d(TAG,"onClick");
                    Intent intent = new Intent(ShareAnimatorActivity.this,SecondShareAnimActivity.class);
                    Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(ShareAnimatorActivity.this,shareImg,getString(R.string.share_pic_str)).toBundle();
                    startActivity(intent,bundle);
                }
            });
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    跳转到的Activity代码:

    public class SecondShareAnimActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_sencond_share_animator_main);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2、Fragment to Fragment跳转实现

    2.1、使用步骤

    1、设置transitionName属性
    Transition 框架需要一个能将当前页面的 View 关联到将要跳转到的页面的办法,下面是为 View 添加 Transition Name 的两种方法:

    • 可以在代码中直接调用 ViewCompat.setTransitionName(),也可以在 Android Lolipop
      系统版本以上的设备中直接调用 setTransitionName()。
    • 在布局的 XML 文件中,直接设置 android:transitionName 属性。

    2、设置FragmentTransaction

    getSupportFragmentManager()
            .beginTransaction()
            .addSharedElement(sharedElement, transitionName)
            .replace(R.id.container, newFragment)
            .addToBackStack(null)
            .commit();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    只需要调用 addSharedElement() 来关联要与 Fragment 共享的 View。

    • 作为参数传递给 addSharedElement() 的 View ,就是第一个 Fragment 中你所想要与即将跳转的
      Fragment 共享的 View。
    • 而这个方法的第二个参数要求填入的 TransitionName,就是在跳转的 Fragment 中的该共享 View 的
      Transition Name。
      • 例如,当前 Fragment 中共享 View 的 transitionName 为 “foo”,即将跳转的 Fragment 中的共享
        View 的 transitionName 为 “bar”,那么在 addSharedElement() 中传递的第二个参数就应该是“bar”。

    3、指定 Transition 动画为共享元素添加的办法:

    调用 setSharedElementEnterTransition() 指定 View 如何从第一个 Fragment 转换为跳转 Fragment 中的 View。

    调用 setSharedElementReturnTransition() 指定 View 在用户点击返回按钮后如何从跳转 Fragment 中回到第一个 Fragment 中。

    记住,返回 Transition 需要在跳转 Fragment 中调用相应的方法,要不然你得不到你想要的效果的。

    当然了,你也可以为任何非共享的 View 设置 Transition 过渡动画,只不过调用的 API 变了:在对应的 Fragment 中调用 setEnterTransition(), setExitTransition(), setReturnTransition(),和 setReenterTransition() 这些方法就可以了。

    2.2、案例说明

    1、TestShareActivity

    public class TestShareActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.share_test);
            Fragment fragment = getSupportFragmentManager().findFragmentByTag(FragmentA.class.getName());
            if (fragment == null) {
                fragment = FragmentA.newInstance();
                getSupportFragmentManager().beginTransaction().add(R.id.share_test,
                        fragment,
                        FragmentA.class.getName())
                        .commit();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    share_test.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
    
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <FrameLayout
            android:id="@+id/share_test"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
    </LinearLayout>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2、ShareElementsFragment1

    public class FragmentA extends Fragment {
        public static final String TAG = FragmentA.class.getSimpleName();
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            return inflater.inflate(R.layout.fragment_a, container, false);
        }
    
        public static FragmentA newInstance() {
            return new FragmentA();
        }
    
        @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            final ImageView imageView = (ImageView) getView().findViewById(R.id.imageView);
            getActivity().findViewById(R.id.btn_click).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Fragment fragmentB = getFragmentManager().findFragmentByTag(TAG);
                    if (fragmentB == null) fragmentB = FragmentB.newInstance();
                    getFragmentManager()
                            .beginTransaction()
                            .addSharedElement(imageView,
                                    ViewCompat.getTransitionName(imageView))
                            .addToBackStack(TAG)
                            .replace(R.id.share_test, fragmentB)
                            .commit();
                }
            });
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    fragment_a.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <ImageView
            android:id="@+id/imageView"
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:transitionName="simple transition name"
            android:background="@color/color_green" />
    
        <Button
            android:id="@+id/btn_click"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Click Me"
            android:textSize="16sp" />
    
    </LinearLayout>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    3、ShareElementsFragment2

    public class FragmentB extends Fragment {
    
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            return inflater.inflate(R.layout.fragment_b, container, false);
        }
    
        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                setSharedElementEnterTransition(
                        TransitionInflater.from(getContext())
                                .inflateTransition(android.R.transition.move));
            }
        }
    
        public static FragmentB newInstance() {
            return new FragmentB();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    fragment_b.xml

    <?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:orientation="vertical">
    
        <ImageView
            android:id="@+id/imageView"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:transitionName="simple transition name"
            android:background="@color/color_green"
            android:layout_gravity="center_horizontal"/>
    
    </LinearLayout>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    3、Navigation + 共享元素+ recyclerview 跳转实现

    3.1、使用步骤

    • 1、设置transitionName属性
    • 2、定义FragmentNavigatorExtras参数
    • 3、findNavController().navigate 页面跳转
    // 第一步
    holder.item.findViewById<TextView>(R.id.user_name_text).transitionName = myDataset[position]
    
    holder.item.findViewById<ImageView>(R.id.user_avatar_image).transitionName =
                (position % listOfAvatars.size).toString()
    //第二步
    val extras = FragmentNavigatorExtras(
                    holder.item.findViewById<ImageView>(R.id.user_avatar_image)
                            to (position % listOfAvatars.size).toString(),
                    holder.item.findViewById<TextView>(R.id.user_name_text)
                            to myDataset[position]
                )
                holder.item.findNavController().navigate(
                        R.id.action_leaderboard_to_userProfile,
                    bundle,
                    null,
                    extras
                )
    //第三步
    holder.item.findNavController().navigate(
                        R.id.action_leaderboard_to_userProfile,
                    bundle,
                    null,
                    extras
                )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    3.2、案例说明

    Leaderboard

    class Leaderboard : Fragment() {
    
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                                  savedInstanceState: Bundle?): View? {
            // Inflate the layout for this fragment
            val view = inflater.inflate(R.layout.fragment_leaderboard, container, false)
    
            val viewAdapter = MyAdapter(Array(6) { "Person ${it + 1}" })
    
            view.findViewById<RecyclerView>(R.id.leaderboard_list).run {
                // use this setting to improve performance if you know that changes
                // in content do not change the layout size of the RecyclerView
                setHasFixedSize(true)
    
                // specify an viewAdapter (see also next example)
                adapter = viewAdapter
    
            }
            return view
        }
    }
    
    class MyAdapter(private val myDataset: Array<String>) :
        RecyclerView.Adapter<MyAdapter.ViewHolder>() {
        
        class ViewHolder(val item: View) : RecyclerView.ViewHolder(item)
    
        // Create new views (invoked by the layout manager)
        override fun onCreateViewHolder(parent: ViewGroup,
                                        viewType: Int): ViewHolder {
            // create a new view
            val itemView = LayoutInflater.from(parent.context)
                .inflate(R.layout.list_view_item, parent, false)
    
            return ViewHolder(itemView)
        }
    
        // Replace the contents of a view (invoked by the layout manager)
        @SuppressLint("CutPasteId")
        override fun onBindViewHolder(holder: ViewHolder, position: Int) {
            // - get element from your dataset at this position
            // - replace the contents of the view with that element
            holder.item.findViewById<TextView>(R.id.user_name_text).text = myDataset[position]
            holder.item.findViewById<TextView>(R.id.user_name_text).transitionName = myDataset[position]
    
            holder.item.findViewById<ImageView>(R.id.user_avatar_image)
                    .setImageResource(listOfAvatars[position % listOfAvatars.size])
            holder.item.findViewById<ImageView>(R.id.user_avatar_image).transitionName =
                (position % listOfAvatars.size).toString()
            holder.item.setOnClickListener {
                val bundle = Bundle()
                bundle.apply {
                    putString(USERNAME_KEY, myDataset[position])
                    putInt(USER_AVATAR_KEY, position % listOfAvatars.size)
                }
                val extras = FragmentNavigatorExtras(
                    holder.item.findViewById<ImageView>(R.id.user_avatar_image)
                            to (position % listOfAvatars.size).toString(),
                    holder.item.findViewById<TextView>(R.id.user_name_text)
                            to myDataset[position]
                )
                holder.item.findNavController().navigate(
                        R.id.action_leaderboard_to_userProfile,
                    bundle,
                    null,
                    extras
                )
        }
    
        // Return the size of your dataset (invoked by the layout manager)
        override fun getItemCount() = myDataset.size
    
        companion object {
            const val USERNAME_KEY = "userName"
            const val USER_AVATAR_KEY = "userAvatar"
    
        }
    }
    
    public val listOfAvatars = listOf(
        R.drawable.avatar_1_raster,
        R.drawable.avatar_2_raster,
        R.drawable.avatar_3_raster,
        R.drawable.avatar_4_raster,
        R.drawable.avatar_5_raster,
        R.drawable.avatar_6_raster
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87

    fragment_leaderboard.xml

    <?xml version="1.0" encoding="utf-8"?>
    
    <androidx.recyclerview.widget.RecyclerView
        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:id="@+id/leaderboard_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:context="com.example.android.navigationadvancedsample.listscreen.Leaderboard"
        tools:listitem="@layout/list_view_item"/>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述

    list_view_item.xml

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout 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="wrap_content"
        android:background="@android:color/background_light"
        tools:layout_editor_absoluteY="81dp">
    
    
        <ImageView
            android:id="@+id/user_avatar_image"
            android:layout_width="69dp"
            android:layout_height="69dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginBottom="8dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:background="@drawable/avatar_5_raster"
            app:srcCompat="@drawable/circle"
            tools:background="@tools:sample/avatars"
            tools:srcCompat="@drawable/circle"
            android:contentDescription="@string/profile_image"/>
    
    
        <TextView
            android:id="@+id/user_name_text"
            android:layout_width="228dp"
            android:layout_height="28dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:text=""
            android:textAppearance="@style/TextAppearance.AppCompat.Subhead"
            android:textSize="22sp"
            app:layout_constraintBottom_toTopOf="@+id/user_points_text"
            app:layout_constraintStart_toEndOf="@+id/user_avatar_image"
            app:layout_constraintTop_toTopOf="parent"
            tools:text="@tools:sample/full_names"
            android:layout_marginLeft="8dp" />
    
        <TextView
            android:id="@+id/user_points_text"
            android:layout_width="228dp"
            android:layout_height="21dp"
            android:layout_marginBottom="8dp"
            android:layout_marginStart="8dp"
            android:text="@string/user_points"
            android:textSize="16sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toEndOf="@+id/user_avatar_image"
            app:layout_constraintTop_toBottomOf="@+id/user_name_text"
            tools:text="10,000 pts"
            android:layout_marginLeft="8dp" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    在这里插入图片描述

    UserProfile

    class UserProfile : Fragment() {
    
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                                  savedInstanceState: Bundle?): View? {
    
    
            val view = inflater.inflate(R.layout.fragment_user_profile, container, false)
    
            val name = arguments?.getString(USERNAME_KEY) ?: "Ali Connors"
            val avatarPosition = arguments?.getInt(USER_AVATAR_KEY) ?: 0
    
            view.findViewById<TextView>(R.id.profile_user_name).transitionName = name
            view.findViewById<TextView>(R.id.profile_user_name).text = name
    
            view.findViewById<ImageView>(R.id.profile_pic).transitionName = avatarPosition.toString()
            view.findViewById<ImageView>(R.id.profile_pic)
                .setImageResource(listOfAvatars[avatarPosition])
            return view
        }
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            sharedElementEnterTransition = TransitionInflater.from(requireContext())
                .inflateTransition(android.R.transition.move)
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    fragment_user_profile.xml

    <?xml version="1.0" encoding="utf-8"?>
    
    <androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/profiler_constraint_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorAccent"
        tools:context="com.example.android.navigationadvancedsample.listscreen.UserProfile"
        tools:layout_editor_absoluteY="81dp">
    
        <ImageView
            android:id="@+id/profile_pic"
            android:layout_width="240dp"
            android:layout_height="240dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="64dp"
            android:layout_marginEnd="8dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:background="@drawable/avatar_6_raster"
            app:srcCompat="@drawable/purple_frame"
            tools:background="@tools:sample/avatars[6]"
            tools:src="@drawable/purple_frame" />
    
        <View
                android:id="@+id/user_data_card"
                android:layout_width="0dp"
                android:layout_height="141dp"
                android:layout_marginTop="64dp"
                android:background="@drawable/rounded_rect"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/profile_pic"
                app:layout_constraintVertical_bias="1.0"/>
    
        <TextView
            android:id="@+id/profile_user_name"
            android:gravity="center_horizontal"
            android:layout_width="0dp"
            android:layout_height="40dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="8dp"
            android:text="@string/profile_name_1"
            android:textAlignment="center"
            android:textColor="@color/colorAccent"
            android:textSize="30sp"
            android:textStyle="bold"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/user_data_card" />
    
        <include
            layout="@layout/user_card"
            android:layout_width="0dp"
            android:layout_height="120dp"
            android:layout_marginStart="16dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="24dp"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="24dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/profile_user_name"/>
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    在这里插入图片描述

    参考

    1、在目的地之间添加动画过渡效果
    2、Android高阶转场动画-ShareElement完全攻略

  • 相关阅读:
    SQL Server修改表结构
    【java】力扣 合并两个有序链表
    B树和B+树的区别
    重学java 63.IO流 字节流 ④ 文件复制
    MATLAB算法实战应用案例精讲-【数据分析】数据仓库-数据治理
    拼多多分类ID搜索商品数据分析接口(商品列表数据,商品销量数据,商品详情数据)代码对接教程
    Qt篇——QChartView获取鼠标停留位置的数值
    c语言包含的元素
    C++类与对象,构造函数,析构函数,拷贝构造函数
    孩子自律性不够?猿辅导:计划表要注意“留白”给孩子更多掌控感
  • 原文地址:https://blog.csdn.net/JMW1407/article/details/125736468