view的事件分发可参考:事件分发
实现效果
吸顶、嵌套滑动的解决
上下滑动:当滑动下方的recyclerView的时候,先和上方的imageView一起滑动,等imageView完全滑动完再滑动recyclerView
左右滑动:实现tab的切换
吸顶:当imageView的滑动完后,tabLayout的一栏,紧贴最上方
部分代码逻辑
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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"
tools:context=".MainActivity"
android:orientation="vertical">
<com.example.testone.mynestedscroll.MyNestedScrollLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ImageView
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="300dp"
android:scaleType="fitXY"
android:src="@drawable/panda1"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#F3F3FA"
/>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</LinearLayout>
</com.example.testone.mynestedscroll.MyNestedScrollLayout>
</LinearLayout>
fragment_tab.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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="wrap_content"
android:layout_height="wrap_content"
android:background="#1AFD9C "
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
item_recycler_view.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="wrap_content"
android:orientation="vertical"
>
<TextView
android:id="@+id/recycler_test_text_tv"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#ccc"
android:text="hello"
android:textSize="100px"
android:gravity="center"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#fff"
/>
</LinearLayout>
MyPageAdapter
public class MyPageAdapter extends FragmentStateAdapter {
private List<Fragment> data;
public MyPageAdapter(@NonNull FragmentActivity fragmentActivity, List<Fragment> data) {
super(fragmentActivity);
this.data = data;
}
@NonNull
@Override
public Fragment createFragment(int position) {
return data.get(position);
}
@Override
public int getItemCount() {
return data.size();
}
}
MyRecyclerViewAdapter
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.MyViewHolder> {
Context context;
List<String> strList;
public MyRecyclerViewAdapter(Context context, List<String> strList){
this.context = context;
this.strList = strList;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_recycler_view, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, final int position) {
holder.textView.setText(strList.get(position));
holder.textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(context, "点击了"+strList.get(position), Toast.LENGTH_SHORT).show();
}
});
}
@Override
public int getItemCount() {
return strList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView textView;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.recycler_test_text_tv);
}
}
}
MyNestedScrollLayout
public class MyNestedScrollLayout extends NestedScrollView {
private static final String TAG = "MyNestedScrollLayout";
private ViewGroup contentView;
private View topView;
public MyNestedScrollLayout(@NonNull Context context) {
super(context);
}
public MyNestedScrollLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MyNestedScrollLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
// 获取第一个孩子的第一个孩子
topView = ((ViewGroup) getChildAt(0)).getChildAt(0);
// 获取第一个孩子的第二个孩子
contentView = (ViewGroup)((ViewGroup)getChildAt(0)).getChildAt(1);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// 调整contentView的高度为父容器高度,使之填充布局,避免父容器滚动后出现空白
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
ViewGroup.LayoutParams lp = contentView.getLayoutParams();
lp.height = getMeasuredHeight();
contentView.setLayoutParams(lp);
}
// 让父亲先滑动,至父亲完全滑动不可见,自己再滑动
@Override
public void onNestedPreScroll(@NonNull View target, int dx, int dy, @NonNull int[] consumed, int type) {
boolean hideTop = dy > 0 && getScrollY() < topView.getMeasuredHeight();
if (hideTop) {
scrollBy(0, dy);
consumed[1] = dy; // 消费了多少,如果没有,就会重复滑动
}
}
}
TabFragment
public class TabFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tab, container, false);
RecyclerView recyclerView;
MyRecyclerViewAdapter myRecyclerViewAdapter;
List<String> strList = new ArrayList<>();
for (int i=0; i<30; i++){
strList.add(""+i);
}
myRecyclerViewAdapter = new MyRecyclerViewAdapter(view.getContext(), strList);
recyclerView = view.findViewById(R.id.recycler_view_1);
recyclerView.setLayoutManager(new LinearLayoutManager(view.getContext()));
recyclerView.setAdapter(myRecyclerViewAdapter);
return view;
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
ArrayList<Fragment> fragmentList = new ArrayList<>();
ViewPager2 viewPager;
MyPageAdapter myPageAdapter;
TabLayout tab_layout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TabFragment tabFragment1 = new TabFragment();
TabFragment tabFragment2 = new TabFragment();
TabFragment tabFragment3 = new TabFragment();
fragmentList.add(tabFragment1);
fragmentList.add(tabFragment2);
fragmentList.add(tabFragment3);
viewPager = findViewById(R.id.view_pager);
myPageAdapter = new MyPageAdapter(this, fragmentList);
viewPager.setAdapter(myPageAdapter);
tab_layout = findViewById(R.id.tab_layout);
new TabLayoutMediator(tab_layout, viewPager, new TabLayoutMediator.TabConfigurationStrategy() {
@Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
tab.setText("TAB-"+position);
}
}).attach();
}
}
演示源码地址:
完整演示代码:TabLayout-ViewPager2
持续努力,不断输出中…