天天看點

Android ViewPager2 真的香麼?

      Google 前段時間出了新品 ViewPager2 ,據說意在替代舊版 ViewPager,功能更強大使用更友善;真的這麼香麼,小菜嘗試學習一下!

優勢

  1. 支援 RTL 布局,稍後介紹;
  2. 支援垂直方向切換;
  3. 支援 Fragment 集合重新整理,即 notifyDataSetChanged;

版本

      ViewPager2 目前處于預覽版,還沒有合并到主分支,可能還會有一些隐藏小問題,建議大家先嘗試一下;

implementation 'androidx.viewpager2:viewpager2:1.0.0-alpha02'           

問題

      小菜嘗試第一步要引入 ViewPager2,而此時就出現一個大問題,如下:

      小菜目前 SDK 已是最新版本,首先按照提示在 AndroidManifest->application 添加錯誤中要求的,但是并不能解決問題,之後查閱了很多資料,發現 Androidx 與 Android support 庫 不共存,這可真是麻煩了,如果在實際的項目中直接用可麻煩大了;

解決

      既然不相容,隻好先轉到 Androidx 庫下,chenzhenlindx大神的

部落格

很有幫助;

  1. 工程 -> Refactor -> Migrate to Androidx;
  2. 提示是否儲存以前工程 zip 檔案,看個人需求;
  3. 按提示 Do Refactor 重構即可;

嘗試

      小菜嘗試綁定不同背景色和文字内容;與 ViewPager 不同的是,擴充卡需要使用 RecyclerView.Adapte,這也意味着綁定資料的方式更靈活,小菜為了測試 ViewPager2 新特性,設定了點選事件;

  1. 借助 setOrientation() 方法可以動态改變切換方向,水準或豎直;
  2. 借助 notifyDataSetChanged() 方法可以實時更新資料;
  3. 借助 setLayoutDirection() 方法可以動态調整内容展示方位,從左到右或從右到左;

      此時感覺 ViewPager2 真的很友善,尤其是實時更新資料和動态調整切換方向,真香!

public class ViewPagerActivity extends AppCompatActivity implements MyAdapter.OnItemClickListener {

    private ViewPager2 mVp;
    private List<Integer> list = new ArrayList<Integer>();
    private MyAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view_pager);

        if (list != null) list.clear();
        list.add(Color.RED);
        list.add(Color.GRAY);
        list.add(Color.BLUE);
        list.add(Color.YELLOW);
        mVp = (ViewPager2) findViewById(R.id.view_pager);
        adapter = new MyAdapter(this, list);
        mVp.setAdapter(adapter);
        adapter.setOnItemClickListener(this);
    }

    @Override
    public void onItemClick(int position) {
        Toast.makeText(getApplication(), "目前position=" + (position + 1), Toast.LENGTH_SHORT).show();
        switch (position){
            case 0:
                //mVp.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
                break;
            case 1:
                list.set(position, Color.GREEN);
                adapter.notifyDataSetChanged();
                break;
            case 2:
                mVp.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
                break;
            case 3:
                mVp.setOrientation(ViewPager2.ORIENTATION_VERTICAL);
                break;
        }
    }
}

class MyAdapter extends RecyclerView.Adapter {

    Context context;
    List<Integer> list;

    MyAdapter(Context context, List<Integer> list) {
        this.context = context;
        this.list = list;
    }

    private OnItemClickListener mOnItemClickListener;

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.mOnItemClickListener = onItemClickListener;
    }

    public interface OnItemClickListener {
        void onItemClick(int position);
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view_pager, parent, false);
        final MyViewHolder mViewHolder = new MyViewHolder(v);
        v.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mOnItemClickListener != null) {
                    mOnItemClickListener.onItemClick((Integer) v.getTag());
                    if((Integer) v.getTag()==0){
                        mViewHolder.mTv.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
                    }
                }
            }
        });
        return mViewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
        ((MyViewHolder) holder).mLay.setBackgroundColor(list.get(position));
        ((MyViewHolder) holder).mTv.setText("目前 position = "+(position+1));
        ((MyViewHolder) holder).itemView.setTag(position);
    }

    @Override
    public int getItemCount() {
        return list != null ? list.size() : 0;
    }

    class MyViewHolder extends RecyclerView.ViewHolder {
        LinearLayout mLay;
        TextView mTv;

        public MyViewHolder(View itemView) {
            super(itemView);
            mLay = (LinearLayout) itemView.findViewById(R.id.item_view_pager_lay);
            mTv = (TextView) itemView.findViewById(R.id.item_view_pager_tv);
        }
    }
}
           

擴充

      小菜以前沒有注意過 supportsRtl 屬性,實際很久以前就有了,根據設定内容居左或居右;

  1. 需要 AndroidManifest->application 中添加 android:supportsRtl="true" 屬性;
  2. 内邊距和外邊距建議設定 start/end 方式;
  3. ViewPager2 中設定 setLayoutDirection 時,整個 ViewPager2 不僅子 item 内容反向,整體也反向;隻有子 item 設定 setLayoutDirection 時會反向。

小結

      小菜在學習過程中發現 ViewPager2 确實有很大優勢,隻是目前還沒有釋出到正式版,而且對于版本适配也會有一定難度,對于 Fragment 的懶加載與預加載還有待研究;但是學習體驗一下還是很有幫助的!

      如果有不對的地方還希望多多指出!