MainActivity1 列表展示,使用共享元素完成页面间的切换
package com.example.animactivity;
import android.annotation.SuppressLint;
import android.app.ActivityOptions;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.transition.ChangeBounds;
import android.transition.Fade;
import android.transition.TransitionSet;
import android.view.View;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.app.ActivityOptionsCompat;
import androidx.core.view.ViewCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.listener.OnItemClickListener;
import java.util.ArrayList;
public class MainActivity1 extends AppCompatActivity {
private RecyclerView main1_rv;
private Img1Adapter img1Adapter;
private ArrayList<Bean> img_list;
@SuppressLint("MissingInflatedId")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
main1_rv = findViewById(R.id.main1_rv);
initData();
img1Adapter = new Img1Adapter(getApplicationContext(), R.layout.main1_item_layout, img_list);
main1_rv.setLayoutManager(new LinearLayoutManager(this));
main1_rv.setAdapter(img1Adapter);
ActivityCompat.startPostponedEnterTransition(this);
img1Adapter.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(@NonNull BaseQuickAdapter<?, ?> baseQuickAdapter, @NonNull View view, int i) {
ImageView img1 = view.findViewById(R.id.img1);
jumpToNextActivity(img1, img_list.get(i));
}
});
}
private void initData() {
img_list = new ArrayList<>();
img_list.add(new Bean(R.drawable.img, "name0"));
img_list.add(new Bean(R.drawable.img1, "name1"));
img_list.add(new Bean(R.drawable.img2, "name2"));
img_list.add(new Bean(R.drawable.img3, "name3"));
img_list.add(new Bean(R.drawable.img4, "name4"));
img_list.add(new Bean(R.drawable.img5, "name5"));
img_list.add(new Bean(R.drawable.img6, "name6"));
img_list.add(new Bean(R.drawable.img7, "name7"));
img_list.add(new Bean(R.drawable.img8, "name8"));
img_list.add(new Bean(R.drawable.img9, "name9"));
img_list.add(new Bean(R.drawable.img10, "name10"));
}
/**
* 共享元素跳转
*
* @param img1
*/
private void jump(ImageView img1) {
Intent intent = new Intent(MainActivity1.this, MainActivity2.class);
ActivityOptionsCompat sharedElement = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity1.this, img1, "shared element");
startActivity(intent, sharedElement.toBundle());
}
/**
* 给跳转设置时间
*
* @param img1
* @param data
*/
private void jumpToNextActivity(ImageView img1, Bean data) {
// 创建一个TransitionSet,包含了Fade和ChangeBounds两种过渡效果
TransitionSet transition = new TransitionSet()
.addTransition(new Fade(Fade.OUT))
.addTransition(new ChangeBounds())
.addTransition(new Fade(Fade.IN));
// 设置过渡时间为500毫秒
transition.setDuration(500);
// 应用过渡到Activity或Fragment的共享元素
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(MainActivity1.this, img1, "shared element");
// 启动另一个Activity
Intent intent = new Intent(MainActivity1.this, MainActivity2.class);
intent.putExtra("data_imgId", data.imgId);
intent.putExtra("data_imgDes", data.imgDes);
ActivityCompat.startActivity(MainActivity1.this, intent, options.toBundle());
}
}
activity_main
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
tools:context=".MainActivity1">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/main1_rv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
MainActivity2(主要是查看跳转过来的元素)
package com.example.animactivity;
import android.annotation.SuppressLint;
import android.app.ActivityOptions;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.Typeface;
import android.os.Bundle;
import android.transition.ChangeBounds;
import android.transition.Fade;
import android.transition.Slide;
import android.transition.TransitionSet;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.app.ActivityCompat;
import androidx.core.app.ActivityOptionsCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import java.util.ArrayList;
public class MainActivity2 extends AppCompatActivity implements View.OnClickListener {
private GestureDetector mGestureDetector;
private ImageView img2;
private TabLayout tabLayout;
private ViewPager2 viewPager2;
private AppBarLayout appBarLayout;
private TabLayoutMediator mediator;
private ArrayList<TestFragment> testFragments;
private TextView head_tv;
private ConstraintLayout layout_header;
private int dataImgId;
private String dataImgDes;
@SuppressLint("MissingInflatedId")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Intent intent = getIntent();
if (intent != null) {
dataImgId = intent.getIntExtra("data_imgId", R.id.img1);
dataImgDes = intent.getStringExtra("data_imgDes");
}
img2 = findViewById(R.id.img2);
img2.setImageDrawable(getDrawable(dataImgId));
img2.setOnClickListener(this);
head_tv = findViewById(R.id.head_tv);
head_tv.setText(dataImgDes);
tabLayout = findViewById(R.id.tab_layout);
viewPager2 = findViewById(R.id.view_pager);
appBarLayout = findViewById(R.id.appBarLayout);
layout_header = findViewById(R.id.layout_header);
layout_header.setOnScrollChangeListener(new View.OnScrollChangeListener() {
@Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
if (scrollY - oldScrollY > 100) {
// // 用户向下滑动
// jumpTo();
Toast.makeText(MainActivity2.this, "下滑了", Toast.LENGTH_SHORT).show();
jumpToNextActivity();
}
}
});
initViewPager();
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int i) {
if (i == 0) {
if (tabLayout.getVisibility() == View.VISIBLE) {
tabLayout.setVisibility(View.GONE);
appBarLayout.setLiftOnScrollTargetView(layout_header);
}
} else {
if (tabLayout.getVisibility() == View.GONE) {
tabLayout.setVisibility(View.VISIBLE);
}
}
}
});
// 创建一个GestureDetector实例
mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
// 在这里处理下滑手势逻辑
// if (e1.getY() - e2.getY() > 100 && Math.abs(velocityY) > 200) {
// // 处理下滑手势
// Toast.makeText(MainActivity2.this, "下滑手势", Toast.LENGTH_SHORT).show();
// return true;
// }
return false;
}
@Override
public boolean onScroll(@Nullable MotionEvent e1, @NonNull MotionEvent e2, float distanceX, float distanceY) {
if (e2.getY() - e1.getY() > 100) {
// // 用户向下滑动
// jumpTo();
jumpToNextActivity();
return true;
}
return false;
}
});
ActivityCompat.startPostponedEnterTransition(this);
}
private void initViewPager() {
final String[] tabs = new String[]{"关注", "推荐", "最新0"};
testFragments = new ArrayList<>();
for (String tab : tabs) {
testFragments.add(TestFragment.newInstance(tab));
}
//禁用预加载
viewPager2.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT);
//Adapter
viewPager2.setAdapter(new FragmentStateAdapter(getSupportFragmentManager(), getLifecycle()) {
@NonNull
@Override
public Fragment createFragment(int position) {
//FragmentStateAdapter内部自己会管理已实例化的fragment对象。
// 所以不需要考虑复用的问题
return testFragments.get(position);
}
@Override
public int getItemCount() {
return testFragments.size();
}
});
//viewPager 页面切换监听监听
viewPager2.registerOnPageChangeCallback(changeCallback);
mediator = new TabLayoutMediator(tabLayout, viewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
@Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
tab.setText(tabs[position]);
}
});
//要执行这一句才是真正将两者绑定起来
mediator.attach();
}
private int chosePosition = 0;
private ViewPager2.OnPageChangeCallback changeCallback = new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
//可以来设置选中时tab的大小
testFragments.get(position).setOnMyItemClickListener(new TestFragment.OnMyItemClickListener() {
@Override
public void setItemPostion(String type, int position, Bean data) {
chosePosition = position;
head_tv.setText(type + "===" + data.imgDes);
img2.setImageDrawable(getDrawable(data.imgId));
}
});
}
};
private void jumpTo() {
Intent intent = new Intent(MainActivity2.this, MainActivity3.class);
// ViewCompat.setTransitionName(img2, "shared element");
ActivityOptionsCompat sharedElement = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity2.this, img2, "shared element");
// TransOneActivity, 启动方法没变;
startActivity(
intent,
sharedElement.toBundle());
}
private void jumpToNextActivity() {
ArrayList<Bean> allData = testFragments.get(0).getAllData();
allData.add(0, allData.get(chosePosition));
// 创建一个TransitionSet,包含了Fade和ChangeBounds两种过渡效果
TransitionSet transition = new TransitionSet()
.addTransition(new Fade(Fade.OUT))
.addTransition(new ChangeBounds())
.addTransition(new Fade(Fade.IN));
// 设置过渡时间为500毫秒
transition.setDuration(500);
// 应用过渡到Activity或Fragment的共享元素
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(MainActivity2.this, img2, "shared element");
// 启动另一个Activity
Intent intent = new Intent(MainActivity2.this, MainActivity3.class);
intent.putExtra("all_data", allData);
intent.putExtra("chose_position", chosePosition);
ActivityCompat.startActivity(MainActivity2.this, intent, options.toBundle());
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.img2) {
jumpToNextActivity();
}
}
}
activity_main2
<?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="match_parent"
android:orientation="vertical"
tools:context=".MainActivity2">
<ImageView
android:id="@+id/img2"
android:layout_width="match_parent"
android:layout_height="300dp"
android:scaleType="fitXY"
android:src="@drawable/img2"
android:transitionName="shared element"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/img2">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsingToolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:expandedTitleMarginEnd="0dp"
app:expandedTitleMarginStart="0dp"
app:expandedTitleMarginTop="?attr/actionBarSize"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<include
android:id="@+id/layout_header"
layout="@layout/layout_header"
app:layout_collapseMode="parallax" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/img2"
app:tabGravity="center"
app:tabIndicatorColor="#ff678f"
app:tabIndicatorFullWidth="false"
app:tabIndicatorHeight="2dp"
app:tabMode="scrollable"
app:tabSelectedTextColor="#ff678f"
app:tabTextColor="#333333"
app:tabUnboundedRipple="true" />
</androidx.constraintlayout.widget.ConstraintLayout>
package com.example.animactivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.listener.OnItemClickListener;
import java.util.ArrayList;
/**
* @Description
* @Author xudan
* @CreateTime 2024/4/22
*/
public class TestFragment extends Fragment implements OnItemClickListener {
private View rootView;
private RecyclerView rv;
private MyAdapter myAdapter;
private String fragment_type;
public static TestFragment newInstance(String text) {
Bundle args = new Bundle();
args.putString("text", text);
TestFragment fragment = new TestFragment();
fragment.setArguments(args);
return fragment;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
fragment_type = getArguments().getString("text");
rootView = inflater.inflate(R.layout.fragment_test, container, false);
rv = rootView.findViewById(R.id.rv);
rv.setLayoutManager(new LinearLayoutManager(getContext()));
initData();
myAdapter = new MyAdapter(getActivity(), R.layout.rv_layout_item, img_list);
rv.setAdapter(myAdapter);
myAdapter.setOnItemClickListener(this);
return rootView;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
TextView textView = rootView.findViewById(R.id.text_view);
String text = getArguments() != null ? getArguments().getString("text") : null;
textView.setText(text);
}
private ArrayList<Bean> img_list;
private void initData() {
img_list = new ArrayList<>();
img_list.add(new Bean(R.drawable.img, "name0"));
img_list.add(new Bean(R.drawable.img1, "name1"));
img_list.add(new Bean(R.drawable.img2, "name2"));
img_list.add(new Bean(R.drawable.img3, "name3"));
img_list.add(new Bean(R.drawable.img4, "name4"));
img_list.add(new Bean(R.drawable.img5, "name5"));
img_list.add(new Bean(R.drawable.img6, "name6"));
img_list.add(new Bean(R.drawable.img7, "name7"));
img_list.add(new Bean(R.drawable.img8, "name8"));
img_list.add(new Bean(R.drawable.img9, "name9"));
img_list.add(new Bean(R.drawable.img10, "name10"));
}
@Override
public void onItemClick(@NonNull BaseQuickAdapter<?, ?> baseQuickAdapter, @NonNull View view, int i) {
if (onMyItemClickListener != null) {
onMyItemClickListener.setItemPostion(fragment_type, i, img_list.get(i));
}
}
private OnMyItemClickListener onMyItemClickListener;
public void setOnMyItemClickListener(OnMyItemClickListener onMyItemClickListener) {
this.onMyItemClickListener = onMyItemClickListener;
}
public ArrayList<Bean> getAllData() {
return img_list;
}
public interface OnMyItemClickListener {
void setItemPostion(String type, int postion, Bean data);
}
}
fragment_test
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center">
<TextView
android:id="@+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="#DC9494"
android:gravity="center"
android:textSize="18sp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
MainActivity3(实现类似于抖音效果的滑动)
package com.example.animactivity;
import android.annotation.SuppressLint;
import android.os.Build;
import android.os.Bundle;
import android.view.Window;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import java.util.ArrayList;
public class MainActivity3 extends AppCompatActivity {
private ViewPager2 main3_vp2;
private ArrayList<Bean> list;
private int chosePosition;
@SuppressLint("MissingInflatedId")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
list = (ArrayList<Bean>) getIntent().getSerializableExtra("all_data");
chosePosition = getIntent().getIntExtra("chose_position", 0);
ActivityCompat.startPostponedEnterTransition(this);
main3_vp2 = findViewById(R.id.main3_vp2);
main3_vp2.setAdapter(new FragmentStateAdapter(this) {
@NonNull
@Override
public Fragment createFragment(int position) {
return DetialFragment.newInstance(list.get(position));
}
@Override
public int getItemCount() {
return list.size();
}
});
main3_vp2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
Toast.makeText(MainActivity3.this, "切换到第" + position + "个", Toast.LENGTH_SHORT).show();
}
@Override
public void onPageScrollStateChanged(int state) {
super.onPageScrollStateChanged(state);
}
});
}
}
activity_main3
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity3">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/main3_vp2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" />
</FrameLayout>
关于上述:要点如下:
共享元素切换
private void jumpToNextActivity(ImageView img1, Bean data) {
// 创建一个TransitionSet,包含了Fade和ChangeBounds两种过渡效果
TransitionSet transition = new TransitionSet()
.addTransition(new Fade(Fade.OUT))
.addTransition(new ChangeBounds())
.addTransition(new Fade(Fade.IN));
// 设置过渡时间为500毫秒
transition.setDuration(500);
// 应用过渡到Activity或Fragment的共享元素
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(MainActivity1.this, img1, "shared element");
// 启动另一个Activity
Intent intent = new Intent(MainActivity1.this, MainActivity2.class);
intent.putExtra("data_imgId", data.imgId);
intent.putExtra("data_imgDes", data.imgDes);
ActivityCompat.startActivity(MainActivity1.this, intent, options.toBundle());
}
使用TabLayout+Viewpager时,注意页面切换监听监听
viewPager2.registerOnPageChangeCallback(changeCallback);
mediator = new TabLayoutMediator(tabLayout, viewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
@Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
tab.setText(tabs[position]);
}
});
//要执行这一句才是真正将两者绑定起来
mediator.attach();
private ViewPager2.OnPageChangeCallback changeCallback = new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
//可以来设置选中时tab的大小
testFragments.get(position).setOnMyItemClickListener(new TestFragment.OnMyItemClickListener() {
@Override
public void setItemPostion(String type, int position, Bean data) {
chosePosition = position;
head_tv.setText(type + "===" + data.imgDes);
img2.setImageDrawable(getDrawable(data.imgId));
}
});
单纯的梳理逻辑,所以demo中的图片加载没有做任何处理,有大图加载可能会导致oom,所以有针对的了解哈