ViewPager和ViewPager2

1.ViewPager简单使用:

   1)定义Layout

  

      2)初始化View

  private void initViews() {
        viewPager = findViewById(R.id.viewpager);
        List list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add("pos: " + i);
        }
        views = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            View view = LayoutInflater.from(this).inflate(R.layout.layout_item, null);
            TextView textView = view.findViewById(R.id.textview);
            textView.setText(list.get(i));
            views.add(view);
        }
        MyPageAdapter pageAdapter = new MyPageAdapter(this, views);
        viewPager.setAdapter(pageAdapter);
    }

    3)PageAdapter

  

public class MyPageAdapter extends PagerAdapter {
    private Context context;
    private List views;

    public MyPageAdapter(Context context, List list) {
        this.context = context;
        this.views = list;
    }

    @Override
    public int getCount() {
        if (views == null) {
            return 0;
        } else {
            return Integer.MAX_VALUE;
        }
    }

    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
        return view == object;
    }

    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        int index = position % views.size();
        Log.e("nyz", "instantiateItem " + position);
        Log.e("nyz", "childCount " + container.getChildCount());
        container.addView(views.get(index));
        return views.get(index);
    }

    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {

        Log.e("nyz", "destroyItem " + position);
        Log.e("nyz", "childCount " + container.getChildCount());
        container.removeView((View) object);
    }

}

2.ViewPager2的简单使用

 1)layout引入ViewPager2

 

   2)Activity中。

  List list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add("pos: " + i);
        }

        viewPager2 = findViewById(R.id.viewpager2);
        //设置ViewPager是纵向滚动,还是横向滚动
//        viewPager2.setOrientation(ViewPager2.ORIENTATION_VERTICAL);
        viewPager2.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
        viewPager2.setAdapter(new MyPageAdapter2(this, list));

 3)Adapter,定义Adapter和定义RecycleView的Adapter是一样的。因为在ViewPager2内部有一个RecycleView。

public class MyPageAdapter2 extends RecyclerView.Adapter {
    private Context context;
    private List list;

    public MyPageAdapter2(Context context, List list) {
        this.context = context;
        this.list = list;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.layout_item, parent,false);
        MyViewHolder viewHolder = new MyViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        ((MyViewHolder) holder).update(list.get(position));
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    class MyViewHolder extends RecyclerView.ViewHolder {
        private TextView textView;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            textView = itemView.findViewById(R.id.textview);
        }

        public void update(String str) {
            textView.setText(str);
        }
    }
}

4)java.lang.IllegalStateException: Pages must fill the whole ViewPager2 (use match_parent)

 Process: com.example.viewpager, PID: 8447
    java.lang.IllegalStateException: Pages must fill the whole ViewPager2 (use match_parent)
        at androidx.viewpager2.widget.ViewPager2$4.onChildViewAttachedToWindow(ViewPager2.java:270)
        at androidx.recyclerview.widget.RecyclerView.dispatchChildAttached(RecyclerView.java:7561)
        at androidx.recyclerview.widget.RecyclerView$5.addView(RecyclerView.java:860)
        at androidx.recyclerview.widget.ChildHelper.addView(ChildHelper.java:107)
        at androidx.recyclerview.widget.RecyclerView$LayoutManager.addViewInt(RecyclerView.java:8601)
        at androidx.recyclerview.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:8559)
        at androidx.recyclerview.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:8547)
        at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1641)
        at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587)
        at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:665)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4134)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3851)
        at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4404)
        at android.view.View.layout(View.java:23750)
        at android.view.ViewGroup.layout(ViewGroup.java:6525)
        at androidx.viewpager2.widget.ViewPager2.onLayout(ViewPager2.java:527)
        at android.view.View.layout(View.java:23750)
        at android.view.ViewGroup.layout(ViewGroup.java:6525)
        at androidx.swiperefreshlayout.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:689)
        at android.view.View.layout(View.java:23750)
        at android.view.ViewGroup.layout(ViewGroup.java:6525)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1582)
        at android.view.View.layout(View.java:23750)
        at android.view.ViewGroup.layout(ViewGroup.java:6525)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at android.view.View.layout(View.java:23750)
        at android.view.ViewGroup.layout(ViewGroup.java:6525)
        at androidx.appcompat.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:536)
        at android.view.View.layout(View.java:23750)
        at android.view.ViewGroup.layout(ViewGroup.java:6525)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at android.view.View.layout(View.java:23750)
        at android.view.ViewGroup.layout(ViewGroup.java:6525)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1582)
        at android.view.View.layout(View.java:23750)
        at android.view.ViewGroup.layout(ViewGroup.java:6525)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at com.android.internal.policy.DecorView.onLayout(DecorView.java:880)
        at android.view.View.layout(View.java:23750)
        at android.view.ViewGroup.layout(ViewGroup.java:6525)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:4082)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3501)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2410)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9402)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1193)
        at android.view.Choreographer.doCallbacks(Choreographer.java:945)
        at android.view.Choreographer.doFrame(Choreographer.java:851)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1175)
        at android.os.Handler.handleCallback(Handler.java:938)

  出现上面的异常的解决方案:

1)解决方案1 在onCreateViewHolder时不能使用下面的方式:

     View view = LayoutInflater.from(context).inflate(R.layout.layout_item,null);

     而应该使用下面的方式,就不会出现上面的异常:

    View view = LayoutInflater.from(context).inflate(R.layout.layout_item, parent,false);

2)解决方案2 动态设置宽高

  View view = LayoutInflater.from(context).inflate(R.layout.layout_item,null);

        ViewGroup.LayoutParams layoutParams =
                new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        view.setLayoutParams(layoutParams);
        

通过上面的异常信息,可以看出来Choreographer的调用流程:

FrameDisplayEventReceiver.run--doFrame---doCallbacks--CallbackRecord.run--TraversalRunnable.run--doTraversal--performTraversals--performLayout--layout--

然后就是熟悉的onLayout onMeasure onDraw.

可以参考另外一篇介绍编舞者的文章:

Choreographer--编舞者源码分析_choreographer 源码分析-CSDN博客

 at android.view.View.layout(View.java:23750)
        at android.view.ViewGroup.layout(ViewGroup.java:6525)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:4082)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3501)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2410)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9402)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1193)
        at android.view.Choreographer.doCallbacks(Choreographer.java:945)
        at android.view.Choreographer.doFrame(Choreographer.java:851)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1175)
        at android.os.Handler.handleCallback(Handler.java:938)

代码下载:

https://download.csdn.net/download/niuyongzhi/88408862

你可能感兴趣的:(android开发,android)