博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
qt 工具栏分隔符_带有分隔线和上下文工具栏的RecyclerView Android
阅读量:2532 次
发布时间:2019-05-11

本文共 19427 字,大约阅读时间需要 64 分钟。

qt 工具栏分隔符

Today we’ll be developing a RecyclerView Android app with contextual toolbar to let us select, delete or mark the rows of a RecyclerView. Furthermore, we’ll place dividers between RecyclerView rows.

今天,我们将开发带有上下文工具栏的RecyclerView Android应用程序,让我们选择,删除或标记RecyclerView的行。 此外,我们将在RecyclerView行之间放置分隔线。

带有分频器和上下文工具栏演示的RecyclerView Android (RecyclerView Android with Dividers and Contextual Toolbar Demo)

We’ll be developing an application that displays the number of rows selected. Our app will allow us to delete, mark, refresh and select all rows.

我们将开发一个显示所选行数的应用程序。 我们的应用程序将允许我们删除,标记,刷新和选择所有行。

A preview of what we’ll going to achieve by the end of this tutorial is given below.

以下是本教程结束时我们将要实现的目标的预览。

RecyclerView Android示例 (RecyclerView Android Example)

ActionMode is used to display the contextual toolbar when a row is long pressed in the list. This enables us to provide a set of alternative toolbar icons.

当在列表中长按一行时, ActionMode用于显示上下文工具栏。 这使我们能够提供一组替代工具栏图标。

We’ll be implementing the four action modes present on the top right.

我们将实现右上角的四种操作模式。

  1. Reload list

    重新载入清单
  2. Mark row text

    标记行文字
  3. Delete row

    删除行
  4. Select all rows

    选择所有行

To implement the Contextual Toolbar and the above actions, we’ll need to implement the ActionMode.Callback interface in our MainActivity.java class.

要实现上下文工具栏和上述操作,我们需要在MainActivity.java类中实现ActionMode.Callback接口。

The ActionMode.Callback interface consists of 4 methods that we’ll be overriding.

ActionMode.Callback接口包含我们将要覆盖的4个方法。

  1. onCreateActionMode: The menu.xml file is inflated in this method.

    onCreateActionMode :在此方法中将menu.xml文件放大。
  2. onPrepareActionMode: This is called every time the Contextual Toolbar is shown.

    onPrepareActionMode :每当显示上下文工具栏时调用。
  3. onActionItemClicked: This is invoked every time a menu item from the Contextual Toolbar is clicked.

    onActionItemClicked :每次单击上下文工具栏中的菜单项时,都会调用此方法。
  4. onDestroyActionMode: This is invoked when the Contextual Toolbar is closed.

    onDestroyActionMode :当上下文工具栏关闭时调用。

RecyclerView android依赖项 (RecyclerView android dependencies)

Let’s start off by adding the following dependencies in our build file.

让我们从在构建文件中添加以下依赖关系开始。

compile 'com.android.support:design:25.3.1'compile 'com.android.support:recyclerview-v7:25.3.1'

Set the activity’s theme to AppTheme.NoActionBar in the Manifest.xml file as shown below.

将活动的主题设置为Manifest.xml文件中的AppTheme.NoActionBar ,如下所示。

RecyclerView Android示例项目结构 (RecyclerView Android Example Project Structure)

The code for activity_main.xml is given below.

下面给出了activity_main.xml的代码。

The code for content_main.xml is given below:

content_main.xml的代码如下:

The layout code for each row of the RecyclerView is given in the file recyclerview_list_row.xml.

RecyclerView每行的布局代码在文件recyclerview_list_row.xml给出。

The background of the RelativeLayout is a StateListDrawable (bg_list_row.xml) that’ll change its background when the row is selected/deselected.

RelativeLayout的背景是StateListDrawable(bg_list_row.xml),当选择/取消选择该行时,它将更改其背景。

The code for bg_list_row.xml is given below:

bg_list_row.xml的代码如下:

The menu that’ll be displayed inside the Contextual Toolbar is defined in the file menu_action_mode.xml as shown below.

上下文工具menu_action_mode.xml将显示的菜单在文件menu_action_mode.xml定义,如下所示。

We’ve created a custom ItemDecoration for displaying dividers for each of the rows. The code for DividerItemDecoration.java is given below.

我们创建了一个自定义ItemDecoration来显示每行的分隔线。 下面给出了DividerItemDecoration.java的代码。

package com.journaldev.recyclerviewdividersandselectors;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Rect;import android.graphics.drawable.Drawable;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.view.View;public class DividerItemDecoration extends RecyclerView.ItemDecoration {    private static final int[] ATTRS = new int[]{            android.R.attr.listDivider    };    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;    private Drawable mDivider;    private int mOrientation;    public DividerItemDecoration(Context context, int orientation) {        final TypedArray a = context.obtainStyledAttributes(ATTRS);        mDivider = a.getDrawable(0);        a.recycle();        setOrientation(orientation);    }    public void setOrientation(int orientation) {        if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {            throw new IllegalArgumentException("wrong orientation");        }        mOrientation = orientation;    }    @Override    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {        if (mOrientation == VERTICAL_LIST) {            drawVertical(c, parent);        } else {            drawHorizontal(c, parent);        }    }    public void drawVertical(Canvas c, RecyclerView parent) {        final int left = parent.getPaddingLeft();        final int right = parent.getWidth() - parent.getPaddingRight();        final int childCount = parent.getChildCount();        for (int i = 0; i < childCount; i++) {            final View child = parent.getChildAt(i);            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child                    .getLayoutParams();            final int top = child.getBottom() + params.bottomMargin;            final int bottom = top + mDivider.getIntrinsicHeight();            mDivider.setBounds(left, top, right, bottom);            mDivider.draw(c);        }    }    public void drawHorizontal(Canvas c, RecyclerView parent) {        final int top = parent.getPaddingTop();        final int bottom = parent.getHeight() - parent.getPaddingBottom();        final int childCount = parent.getChildCount();        for (int i = 0; i < childCount; i++) {            final View child = parent.getChildAt(i);            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child                    .getLayoutParams();            final int left = child.getRight() + params.rightMargin;            final int right = left + mDivider.getIntrinsicHeight();            mDivider.setBounds(left, top, right, bottom);            mDivider.draw(c);        }    }    @Override    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {        if (mOrientation == VERTICAL_LIST) {            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());        } else {            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);        }    }}

The above code creates a divider line (similar to ListView) after each RecyclerView row based on the orientation.

上面的代码根据方向在每个RecyclerView行之后创建一个分隔线(类似于ListView)。

The code for Model.java that holds the data for each row is given below.

下面Model.java了保存每一行数据的Model.java代码。

package com.journaldev.recyclerviewdividersandselectors;public class Model {    String text;    boolean colored;    public Model(String text, boolean colored) {        this.text = text;        this.colored = colored;    }}

The code for RecyclerViewAdapter.java is given below:

下面给出了RecyclerViewAdapter.java的代码:

package com.journaldev.recyclerviewdividersandselectors;import android.content.Context;import android.support.v7.widget.RecyclerView;import android.util.SparseBooleanArray;import android.view.HapticFeedbackConstants;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.RelativeLayout;import android.widget.TextView;import java.util.ArrayList;import java.util.List;public class RecyclerViewAdapter extends RecyclerView.Adapter {    private Context mContext;    private List modelList;    private ClickAdapterListener listener;    private SparseBooleanArray selectedItems;    private static int currentSelectedIndex = -1;    public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener {        public TextView textView;        public RelativeLayout relativeLayout;        public MyViewHolder(View view) {            super(view);            textView = (TextView) view.findViewById(R.id.textView);            relativeLayout = (RelativeLayout) view.findViewById(R.id.relativeLayout);            view.setOnLongClickListener(this);        }        @Override        public boolean onLongClick(View view) {            listener.onRowLongClicked(getAdapterPosition());            view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);            return true;        }    }    public RecyclerViewAdapter(Context mContext, List modelList, ClickAdapterListener listener) {        this.mContext = mContext;        this.modelList = modelList;        this.listener = listener;        selectedItems = new SparseBooleanArray();    }    @Override    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        View itemView = LayoutInflater.from(parent.getContext())                .inflate(R.layout.recyclerview_list_row, parent, false);        return new MyViewHolder(itemView);    }    @Override    public void onBindViewHolder(final MyViewHolder holder, final int position) {        String text = modelList.get(position).text;        holder.textView.setText(text);        if (modelList.get(position).colored)            holder.textView.setTextColor(mContext.getResources().getColor(android.R.color.holo_red_dark));        holder.itemView.setActivated(selectedItems.get(position, false));        applyClickEvents(holder, position);    }    private void applyClickEvents(MyViewHolder holder, final int position) {        holder.relativeLayout.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                listener.onRowClicked(position);            }        });        holder.relativeLayout.setOnLongClickListener(new View.OnLongClickListener() {            @Override            public boolean onLongClick(View view) {                listener.onRowLongClicked(position);                view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);                return true;            }        });    }    @Override    public int getItemCount() {        return modelList.size();    }    public void toggleSelection(int pos) {        currentSelectedIndex = pos;        if (selectedItems.get(pos, false)) {            selectedItems.delete(pos);        } else {            selectedItems.put(pos, true);        }        notifyItemChanged(pos);    }    public void selectAll() {        for (int i = 0; i < getItemCount(); i++)            selectedItems.put(i, true);        notifyDataSetChanged();    }    public void clearSelections() {        selectedItems.clear();        notifyDataSetChanged();    }    public int getSelectedItemCount() {        return selectedItems.size();    }    public List getSelectedItems() {        List items =                new ArrayList(selectedItems.size());        for (int i = 0; i < selectedItems.size(); i++) {            items.add(selectedItems.keyAt(i));        }        return items;    }    public void removeData(int position) {        modelList.remove(position);        resetCurrentIndex();    }    public void updateData(int position) {        modelList.get(position).colored = true;        resetCurrentIndex();    }    private void resetCurrentIndex() {        currentSelectedIndex = -1;    }    public interface ClickAdapterListener {        void onRowClicked(int position);        void onRowLongClicked(int position);    }}

The following code snippet is used to change the state of the StateListDrawable.

以下代码段用于更改StateListDrawable的状态。

holder.itemView.setActivated(selectedItems.get(position, false));

The methods selectAll(), removeData() and updateData() would be invoked from the MainActivity.java based on the menu item clicked.

方法selectAll()removeData()updateData()将基于所单击的菜单项从MainActivity.java中调用。

The code for MainActivity.java is given below.

MainActivity.java的代码如下。

package com.journaldev.recyclerviewdividersandselectors;import android.support.design.widget.FloatingActionButton;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.support.v7.view.ActionMode;import android.support.v7.widget.DefaultItemAnimator;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.Toolbar;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.view.View;import java.util.ArrayList;import java.util.List;import static android.view.View.GONE;public class MainActivity extends AppCompatActivity implements RecyclerViewAdapter.ClickAdapterListener {    RecyclerView recyclerView;    LinearLayoutManager layoutManager;    ArrayList dataModel;    RecyclerViewAdapter mAdapter;    private ActionModeCallback actionModeCallback;    private ActionMode actionMode;    FloatingActionButton fab;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);        setSupportActionBar(toolbar);        fab = (FloatingActionButton) findViewById(R.id.fab);        fab.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                fab.setVisibility(GONE);                populateDataAndSetAdapter();            }        });        recyclerView = (RecyclerView) findViewById(R.id.recycler_view);        recyclerView.setHasFixedSize(true);        layoutManager = new LinearLayoutManager(this);        recyclerView.setLayoutManager(layoutManager);        recyclerView.setItemAnimator(new DefaultItemAnimator());        recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));        actionModeCallback = new ActionModeCallback();        populateDataAndSetAdapter();    }    @Override    public void onRowClicked(int position) {        enableActionMode(position);    }    @Override    public void onRowLongClicked(int position) {        enableActionMode(position);    }    private void enableActionMode(int position) {        if (actionMode == null) {            actionMode = startSupportActionMode(actionModeCallback);        }        toggleSelection(position);    }    private void toggleSelection(int position) {        mAdapter.toggleSelection(position);        int count = mAdapter.getSelectedItemCount();        if (count == 0) {            actionMode.finish();            actionMode = null;        } else {            actionMode.setTitle(String.valueOf(count));            actionMode.invalidate();        }    }    private void selectAll() {        mAdapter.selectAll();        int count = mAdapter.getSelectedItemCount();        if (count == 0) {            actionMode.finish();        } else {            actionMode.setTitle(String.valueOf(count));            actionMode.invalidate();        }        actionMode = null;    }    private class ActionModeCallback implements ActionMode.Callback {        @Override        public boolean onCreateActionMode(ActionMode mode, Menu menu) {            mode.getMenuInflater().inflate(R.menu.menu_action_mode, menu);            return true;        }        @Override        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {            return false;        }        @Override        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {            Log.d("API123", "here");            switch (item.getItemId()) {                case R.id.action_delete:                    // delete all the selected rows                    deleteRows();                    mode.finish();                    return true;                case R.id.action_color:                    updateColoredRows();                    mode.finish();                    return true;                case R.id.action_select_all:                    selectAll();                    return true;                case R.id.action_refresh:                    populateDataAndSetAdapter();                    mode.finish();                    return true;                default:                    return false;            }        }        @Override        public void onDestroyActionMode(ActionMode mode) {            mAdapter.clearSelections();            actionMode = null;        }    }    private void deleteRows() {        List selectedItemPositions =                mAdapter.getSelectedItems();        for (int i = selectedItemPositions.size() - 1; i >= 0; i--) {            mAdapter.removeData(selectedItemPositions.get(i));        }        mAdapter.notifyDataSetChanged();        if (mAdapter.getItemCount() == 0)            fab.setVisibility(View.VISIBLE);        actionMode = null;    }    private void updateColoredRows() {        List selectedItemPositions =                mAdapter.getSelectedItems();        for (int i = selectedItemPositions.size() - 1; i >= 0; i--) {            mAdapter.updateData(selectedItemPositions.get(i));        }        mAdapter.notifyDataSetChanged();        actionMode = null;    }    private void populateDataAndSetAdapter() {        dataModel = new ArrayList();        dataModel.add(new Model("Item 1", false));        dataModel.add(new Model("Item 2", false));        dataModel.add(new Model("Item 3", false));        dataModel.add(new Model("Item 4", false));        dataModel.add(new Model("Item 5", false));        dataModel.add(new Model("Item 6", false));        dataModel.add(new Model("Item 7", false));        dataModel.add(new Model("Item 8", false));        dataModel.add(new Model("Item 9", false));        dataModel.add(new Model("Item 10", false));        dataModel.add(new Model("Item 11", false));        dataModel.add(new Model("Item 12", false));        mAdapter = new RecyclerViewAdapter(this, dataModel, this);        recyclerView.setAdapter(mAdapter);    }}

The following code is used to add dividers between the rows.

以下代码用于在行之间添加分隔符。

recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));

onRowClicked() and onRowLongClicked() are called every time a RecyclerView row is clicked.

每次单击RecyclerView行时,都会调用onRowClicked()onRowLongClicked()

enableActionMode() is used to show the Contextual Toolbar.

enableActionMode()用于显示上下文工具栏。

The Contextual Toolbar displays the number of rows selected based upon the getSelectedItemCount() from the adapter class.

上下文工具栏显示基于适配器类中的getSelectedItemCount()选择的行数。

If all the rows are deleted, we show a floating action button that lets the user populate the RecyclerView with dummy data once again.

如果所有行均被删除,我们将显示一个浮动操作按钮,该按钮使用户可以再次使用伪数据填充RecyclerView。

The output of the above application in action is given below.

下面给出了上面应用程序的输出。

Contextual Toolbar is commonly seen in applications like Whatsapp and Inbox.

上下文工具栏通常在诸如Whatsapp和Inbox之类的应用程序中看到。

This brings an end to the RecyclerView Android example with divider and selectors. You can download the final Android RecyclerViewDividersAndSelectors Project from the link below.

这结束了带有分隔符和选择器的RecyclerView Android示例。 您可以从下面的链接下载最终的Android RecyclerViewDividersAndSelectors项目

Reference:

参考:

翻译自:

qt 工具栏分隔符

转载地址:http://dcqzd.baihongyu.com/

你可能感兴趣的文章
shell——按指定列排序
查看>>
crash 收集
查看>>
507 LOJ 「LibreOJ NOI Round #1」接竹竿
查看>>
UI基础--烟花动画
查看>>
2018. 2.4 Java中集合嵌套集合的练习
查看>>
精通ASP.NET Web程序测试
查看>>
vue 根据不同属性 设置背景
查看>>
51Nod1601 完全图的最小生成树计数 Trie Prufer编码
查看>>
Codeforces 1110D. Jongmah 动态规划
查看>>
android驱动在win10系统上安装的心酸历程
查看>>
优雅的程序员
查看>>
oracle之三 自动任务调度
查看>>
Android dex分包方案
查看>>
ThreadLocal为什么要用WeakReference
查看>>
删除本地文件
查看>>
FOC实现概述
查看>>
base64编码的图片字节流存入html页面中的显示
查看>>
这个大学时代的博客不在维护了,请移步到我的新博客
查看>>
GUI学习之二十一——QSlider、QScroll、QDial学习总结
查看>>
nginx反向代理docker registry报”blob upload unknown"解决办法
查看>>