Эх сурвалжийг харах

rewrite sharee list to recycler view, show can edit in list items

AndyScherzinger 6 жил өмнө
parent
commit
e7a0f493f2

+ 150 - 87
src/main/java/com/owncloud/android/ui/adapter/UserListAdapter.java

@@ -26,12 +26,13 @@ import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.support.annotation.NonNull;
 import android.support.v4.app.FragmentManager;
+import android.support.v7.widget.AppCompatCheckBox;
+import android.support.v7.widget.RecyclerView;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
 import android.widget.ImageView;
 import android.widget.PopupMenu;
 import android.widget.TextView;
@@ -43,7 +44,6 @@ import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.resources.shares.OCShare;
 import com.owncloud.android.lib.resources.shares.ShareType;
 import com.owncloud.android.lib.resources.status.OCCapability;
-import com.owncloud.android.lib.resources.status.OwnCloudVersion;
 import com.owncloud.android.ui.TextDrawable;
 import com.owncloud.android.ui.dialog.ExpirationDatePickerDialogFragment;
 import com.owncloud.android.ui.fragment.util.FileDetailSharingFragmentHelper;
@@ -52,26 +52,30 @@ import com.owncloud.android.utils.ThemeUtils;
 
 import java.io.UnsupportedEncodingException;
 import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
+import java.util.List;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
 
 /**
  * Adapter to show a user/group/email/remote in Sharing list in file details view.
  */
-public class UserListAdapter extends ArrayAdapter implements DisplayUtils.AvatarGenerationListener {
+public class UserListAdapter extends RecyclerView.Adapter<UserListAdapter.UserViewHolder>
+        implements DisplayUtils.AvatarGenerationListener {
 
     private ShareeListAdapterListener listener;
     private OCCapability capabilities;
     private FragmentManager fragmentManager;
     private Context context;
-    private ArrayList<OCShare> shares;
+    private int accentColor;
+    private List<OCShare> shares;
     private float avatarRadiusDimension;
     private Account account;
     private OCFile file;
     private FileDataStorageManager storageManager;
 
-    public UserListAdapter(FragmentManager fragmentManager, Context context, int resource, ArrayList<OCShare> shares,
-                           Account account, OCFile file, ShareeListAdapterListener listener) {
-        super(context, resource);
+    public UserListAdapter(FragmentManager fragmentManager, Context context, List<OCShare> shares, Account account,
+                           OCFile file, ShareeListAdapterListener listener) {
         this.context = context;
         this.fragmentManager = fragmentManager;
         this.shares = shares;
@@ -79,71 +83,88 @@ public class UserListAdapter extends ArrayAdapter implements DisplayUtils.Avatar
         this.account = account;
         this.file = file;
 
-        storageManager = new FileDataStorageManager(account, getContext().getContentResolver());
+        accentColor = ThemeUtils.primaryAccentColor(context);
+        storageManager = new FileDataStorageManager(account, context.getContentResolver());
         capabilities = storageManager.getCapability(account.name);
-
         avatarRadiusDimension = context.getResources().getDimension(R.dimen.user_icon_radius);
     }
 
+    @NonNull
     @Override
-    public int getCount() {
-        return shares.size();
+    public UserViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.file_details_share_user_item, parent, false);
+        return new UserViewHolder(v);
     }
 
     @Override
-    public Object getItem(int position) {
-        return shares.get(position);
-    }
-
-    @Override
-    public long getItemId(int position) {
-        return 0;
-    }
-
-    @Override
-    public @NonNull
-    View getView(final int position, View convertView, @NonNull ViewGroup parent) {
-        View view = convertView;
-        if (view == null) {
-            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-            view = inflater.inflate(R.layout.file_details_share_user_item, parent, false);
-        }
-
+    public void onBindViewHolder(@NonNull UserViewHolder holder, int position) {
         if (shares != null && shares.size() > position) {
-            OCShare share = shares.get(position);
+            final OCShare share = shares.get(position);
 
-            TextView userName = view.findViewById(R.id.userOrGroupName);
-            final ImageView editShareButton = view.findViewById(R.id.editShareButton);
-            ImageView icon = view.findViewById(R.id.userIcon);
             String name = share.getSharedWithDisplayName();
             if (share.getShareType() == ShareType.GROUP) {
-                name = getContext().getString(R.string.share_group_clarification, name);
+                name = context.getString(R.string.share_group_clarification, name);
                 try {
-                    icon.setImageDrawable(TextDrawable.createNamedAvatar(name, avatarRadiusDimension));
+                    holder.avatar.setImageDrawable(TextDrawable.createNamedAvatar(name, avatarRadiusDimension));
                 } catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
-                    icon.setImageResource(R.drawable.ic_group);
+                    holder.avatar.setImageResource(R.drawable.ic_group);
                 }
             } else if (share.getShareType() == ShareType.EMAIL) {
-                name = getContext().getString(R.string.share_email_clarification, name);
+                name = context.getString(R.string.share_email_clarification, name);
                 try {
-                    icon.setImageDrawable(TextDrawable.createNamedAvatar(name, avatarRadiusDimension));
+                    holder.avatar.setImageDrawable(TextDrawable.createNamedAvatar(name, avatarRadiusDimension));
                 } catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
-                    icon.setImageResource(R.drawable.ic_email);
+                    holder.avatar.setImageResource(R.drawable.ic_email);
                 }
             } else {
-                icon.setTag(share.getShareWith());
+                holder.avatar.setTag(share.getShareWith());
                 DisplayUtils.setAvatar(account, share.getShareWith(), this, avatarRadiusDimension,
-                        context.getResources(), storageManager, icon, context);
+                        context.getResources(), storageManager, holder.avatar, context);
             }
-            userName.setText(name);
+            holder.name.setText(name);
+
+            ThemeUtils.tintCheckbox(holder.allowEditing, accentColor);
+            holder.allowEditing.setChecked(canEdit(share));
+            holder.allowEditing.setOnClickListener(v -> allowEditClick(holder.allowEditing, share));
 
-            /// bind listener to edit privileges
-            editShareButton.setOnClickListener(v -> onOverflowIconClicked(v, shares.get(position)));
+            // bind listener to edit privileges
+            holder.editShareButton.setOnClickListener(v -> onOverflowIconClicked(v, holder.allowEditing, share));
+        }
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return shares.get(position).getId();
+    }
+
+    @Override
+    public int getItemCount() {
+        return shares.size();
+    }
+
+    private void allowEditClick(AppCompatCheckBox checkBox, @NonNull OCShare share) {
+        if (!share.isFolder()) {
+            share.setPermissions(listener.updatePermissionsToShare(
+                    share,
+                    canReshare(share),
+                    checkBox.isChecked(),
+                    false,
+                    false,
+                    false
+            ));
+        } else {
+            share.setPermissions(listener.updatePermissionsToShare(
+                    share,
+                    canReshare(share),
+                    checkBox.isChecked(),
+                    checkBox.isChecked(),
+                    checkBox.isChecked(),
+                    checkBox.isChecked()
+            ));
         }
-        return view;
     }
 
-    private void onOverflowIconClicked(View view, OCShare share) {
+    private void onOverflowIconClicked(View view, AppCompatCheckBox allowEditsCheckBox, OCShare share) {
         // use grey as fallback for elements where custom theming is not available
         if (ThemeUtils.themingEnabled(context)) {
             context.getTheme().applyStyle(R.style.FallbackThemingTheme, true);
@@ -153,7 +174,7 @@ public class UserListAdapter extends ArrayAdapter implements DisplayUtils.Avatar
 
         prepareOptionsMenu(popup.getMenu(), share);
 
-        popup.setOnMenuItemClickListener(item -> optionsItemSelected(popup.getMenu(), item, share));
+        popup.setOnMenuItemClickListener(item -> optionsItemSelected(popup.getMenu(), item, allowEditsCheckBox, share));
         popup.show();
     }
 
@@ -164,33 +185,21 @@ public class UserListAdapter extends ArrayAdapter implements DisplayUtils.Avatar
      * @param share the shared file
      */
     private void prepareOptionsMenu(Menu menu, OCShare share) {
-        int sharePermissions = share.getPermissions();
-        boolean isFederated = ShareType.FEDERATED.equals(share.getShareType());
 
         MenuItem reshareItem = menu.findItem(R.id.action_can_reshare);
-        if (isFederated ||
-                (capabilities != null && capabilities.getFilesSharingResharing().isFalse())) {
+        if (isReshareForbidden(share)) {
             reshareItem.setVisible(false);
         }
-        reshareItem.setChecked((sharePermissions & OCShare.SHARE_PERMISSION_FLAG) > 0);
+        reshareItem.setChecked(canReshare(share));
 
-        MenuItem editItem = menu.findItem(R.id.action_can_edit);
-        int anyUpdatePermission = OCShare.CREATE_PERMISSION_FLAG | OCShare.UPDATE_PERMISSION_FLAG |
-                OCShare.DELETE_PERMISSION_FLAG;
-        boolean canEdit = (sharePermissions & anyUpdatePermission) > 0;
-        editItem.setChecked(canEdit);
-
-        OwnCloudVersion serverVersion = AccountUtils.getServerVersion(account);
-        boolean isNotReshareableFederatedSupported = serverVersion.isNotReshareableFederatedSupported();
-        boolean areEditOptionsAvailable = !isFederated || isNotReshareableFederatedSupported;
         MenuItem editCreateItem = menu.findItem(R.id.action_can_edit_create);
         MenuItem editChangeItem = menu.findItem(R.id.action_can_edit_change);
         MenuItem editDeleteItem = menu.findItem(R.id.action_can_edit_delete);
-        if (file.isFolder() && areEditOptionsAvailable) {
+        if (file.isFolder() && isEditOptionsAvailable(share)) {
             /// TODO change areEditOptionsAvailable in order to delete !isFederated
-            editCreateItem.setChecked((sharePermissions & OCShare.CREATE_PERMISSION_FLAG) > 0);
-            editChangeItem.setChecked((sharePermissions & OCShare.UPDATE_PERMISSION_FLAG) > 0);
-            editDeleteItem.setChecked((sharePermissions & OCShare.DELETE_PERMISSION_FLAG) > 0);
+            editCreateItem.setChecked(canCreate(share));
+            editChangeItem.setChecked(canUpdate(share));
+            editDeleteItem.setChecked(canDelete(share));
         } else {
             editCreateItem.setVisible(false);
             editChangeItem.setVisible(false);
@@ -201,31 +210,68 @@ public class UserListAdapter extends ArrayAdapter implements DisplayUtils.Avatar
                 menu.findItem(R.id.action_expiration_date), share.getExpirationDate(), context.getResources());
     }
 
-    private boolean optionsItemSelected(Menu menu, MenuItem item, OCShare share) {
+    private boolean isEditOptionsAvailable(OCShare share) {
+        return !ShareType.FEDERATED.equals(share.getShareType())
+                || AccountUtils.getServerVersion(account).isNotReshareableFederatedSupported();
+    }
+
+    private boolean isReshareForbidden(OCShare share) {
+        return ShareType.FEDERATED.equals(share.getShareType()) ||
+                (capabilities != null && capabilities.getFilesSharingResharing().isFalse());
+    }
+
+    private boolean canEdit(OCShare share) {
+        return (share.getPermissions() &
+                (OCShare.CREATE_PERMISSION_FLAG | OCShare.UPDATE_PERMISSION_FLAG | OCShare.DELETE_PERMISSION_FLAG)) > 0;
+    }
+
+    private boolean canCreate(OCShare share) {
+        return (share.getPermissions() & OCShare.CREATE_PERMISSION_FLAG) > 0;
+    }
+
+    private boolean canUpdate(OCShare share) {
+        return (share.getPermissions() & OCShare.UPDATE_PERMISSION_FLAG) > 0;
+    }
+
+    private boolean canDelete(OCShare share) {
+        return (share.getPermissions() & OCShare.DELETE_PERMISSION_FLAG) > 0;
+    }
+
+    private boolean canReshare(OCShare share) {
+        return (share.getPermissions() & OCShare.SHARE_PERMISSION_FLAG) > 0;
+    }
+
+    private boolean optionsItemSelected(Menu menu, MenuItem item, AppCompatCheckBox allowEditsCheckBox, OCShare share) {
         switch (item.getItemId()) {
-            case R.id.action_can_edit: {
-                item.setChecked(!item.isChecked());
-                if (file.isFolder() && !item.isChecked()) {
-                    menu.findItem(R.id.action_can_edit_create).setChecked(false);
-                    menu.findItem(R.id.action_can_edit_change).setChecked(false);
-                    menu.findItem(R.id.action_can_edit_delete).setChecked(false);
-                }
-                share.setPermissions(updatePermissionsToShare(share, menu));
-                return true;
-            }
             case R.id.action_can_edit_create:
             case R.id.action_can_edit_change:
             case R.id.action_can_edit_delete: {
                 item.setChecked(!item.isChecked());
-                if (item.isChecked() && !menu.findItem(R.id.action_can_edit).isChecked()) {
-                    menu.findItem(R.id.action_can_edit).setChecked(true);
+                if (item.isChecked() && !allowEditsCheckBox.isChecked()) {
+                    allowEditsCheckBox.setChecked(true);
                 }
-                share.setPermissions(updatePermissionsToShare(share, menu));
+                share.setPermissions(
+                        updatePermissionsToShare(
+                                share,
+                                menu.findItem(R.id.action_can_reshare).isChecked(),
+                                allowEditsCheckBox.isChecked(),
+                                menu.findItem(R.id.action_can_edit_create).isChecked(),
+                                menu.findItem(R.id.action_can_edit_change).isChecked(),
+                                menu.findItem(R.id.action_can_edit_delete).isChecked())
+                );
                 return true;
             }
             case R.id.action_can_reshare: {
                 item.setChecked(!item.isChecked());
-                share.setPermissions(updatePermissionsToShare(share, menu));
+                share.setPermissions(
+                        updatePermissionsToShare(
+                                share,
+                                menu.findItem(R.id.action_can_reshare).isChecked(),
+                                allowEditsCheckBox.isChecked(),
+                                menu.findItem(R.id.action_can_edit_create).isChecked(),
+                                menu.findItem(R.id.action_can_edit_change).isChecked(),
+                                menu.findItem(R.id.action_can_edit_delete).isChecked())
+                );
                 return true;
             }
             case R.id.action_unshare: {
@@ -247,14 +293,15 @@ public class UserListAdapter extends ArrayAdapter implements DisplayUtils.Avatar
         }
     }
 
-    private int updatePermissionsToShare(OCShare share, Menu menu) {
+    private int updatePermissionsToShare(OCShare share, boolean canReshare, boolean canEdit, boolean canEditCreate,
+                                         boolean canEditChange, boolean canEditDelete) {
         return listener.updatePermissionsToShare(
                 share,
-                menu.findItem(R.id.action_can_reshare).isChecked(),
-                menu.findItem(R.id.action_can_edit).isChecked(),
-                menu.findItem(R.id.action_can_edit_create).isChecked(),
-                menu.findItem(R.id.action_can_edit_change).isChecked(),
-                menu.findItem(R.id.action_can_edit_delete).isChecked()
+                canReshare,
+                canEdit,
+                canEditCreate,
+                canEditChange,
+                canEditDelete
         );
     }
 
@@ -275,6 +322,22 @@ public class UserListAdapter extends ArrayAdapter implements DisplayUtils.Avatar
         return false;
     }
 
+    class UserViewHolder extends RecyclerView.ViewHolder {
+        @BindView(R.id.userIcon)
+        ImageView avatar;
+        @BindView(R.id.userOrGroupName)
+        TextView name;
+        @BindView(R.id.allow_editing)
+        AppCompatCheckBox allowEditing;
+        @BindView(R.id.editShareButton)
+        ImageView editShareButton;
+
+        UserViewHolder(View itemView) {
+            super(itemView);
+            ButterKnife.bind(this, itemView);
+        }
+    }
+
     public interface ShareeListAdapterListener {
         /**
          * unshare with given sharee {@link OCShare}.

+ 77 - 0
src/main/java/com/owncloud/android/ui/decoration/SimpleListItemDividerDecoration.java

@@ -0,0 +1,77 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Andy Scherzinger
+ * Copyright (C) 2018 Andy Scherzinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.owncloud.android.ui.decoration;
+
+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.DividerItemDecoration;
+import android.support.v7.widget.RecyclerView;
+import android.util.DisplayMetrics;
+import android.view.View;
+
+/**
+ * DividerItemDecoration based on {@link DividerItemDecoration} adding a 72dp left padding.
+ */
+public class SimpleListItemDividerDecoration extends DividerItemDecoration {
+    private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
+
+    private final Rect bounds = new Rect();
+    private Drawable divider;
+    private int leftPadding;
+
+    /**
+     * Default divider will be used
+     */
+    public SimpleListItemDividerDecoration(Context context) {
+        super(context, DividerItemDecoration.VERTICAL);
+        final TypedArray a = context.obtainStyledAttributes(ATTRS);
+        divider = a.getDrawable(0);
+        leftPadding = Math.round(72 * (context.getResources().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));
+    }
+
+    @Override
+    public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
+        canvas.save();
+        final int right;
+        //noinspection AndroidLintNewApi - NewApi lint fails to handle overrides.
+        if (parent.getClipToPadding()) {
+            right = parent.getWidth() - parent.getPaddingRight();
+            canvas.clipRect(leftPadding, parent.getPaddingTop(), right,
+                    parent.getHeight() - parent.getPaddingBottom());
+        } else {
+            right = parent.getWidth();
+        }
+
+        final int childCount = parent.getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final View child = parent.getChildAt(i);
+            parent.getDecoratedBoundsWithMargins(child, bounds);
+            final int bottom = bounds.bottom + Math.round(child.getTranslationY());
+            final int top = bottom - 1;
+            divider.setBounds(leftPadding, top, right, bottom);
+            divider.draw(canvas);
+        }
+        canvas.restore();
+    }
+}

+ 8 - 5
src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java

@@ -31,6 +31,8 @@ import android.support.annotation.NonNull;
 import android.support.design.widget.Snackbar;
 import android.support.v4.app.Fragment;
 import android.support.v7.widget.AppCompatCheckBox;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
 import android.support.v7.widget.SearchView;
 import android.view.LayoutInflater;
 import android.view.Menu;
@@ -53,6 +55,7 @@ import com.owncloud.android.lib.resources.shares.ShareType;
 import com.owncloud.android.lib.resources.status.OCCapability;
 import com.owncloud.android.ui.activity.FileActivity;
 import com.owncloud.android.ui.adapter.UserListAdapter;
+import com.owncloud.android.ui.decoration.SimpleListItemDividerDecoration;
 import com.owncloud.android.ui.dialog.ExpirationDatePickerDialogFragment;
 import com.owncloud.android.ui.dialog.SharePasswordDialogFragment;
 import com.owncloud.android.ui.fragment.util.FileDetailSharingFragmentHelper;
@@ -84,7 +87,7 @@ public class FileDetailSharingFragment extends Fragment implements UserListAdapt
     SearchView searchView;
 
     @BindView(R.id.fdshareUsersList)
-    ListView usersList;
+    RecyclerView usersList;
 
     @BindView(R.id.fdShareNoUsers)
     TextView noList;
@@ -205,14 +208,14 @@ public class FileDetailSharingFragment extends Fragment implements UserListAdapt
 
     private void updateListOfUserGroups() {
         // TODO Refactoring: create a new {@link ShareUserListAdapter} instance with every call should not be needed
-        UserListAdapter mUserGroupsAdapter = new UserListAdapter(getActivity().getSupportFragmentManager(),getActivity().getApplicationContext(),
-                R.layout.share_user_item, shares, account, file, this);
 
         if (shares.size() > 0) {
             usersList.setVisibility(View.VISIBLE);
-            usersList.setAdapter(mUserGroupsAdapter);
+            usersList.setAdapter(new UserListAdapter(getActivity().getSupportFragmentManager(),
+                    getActivity().getApplicationContext(), shares, account, file, this));
+            usersList.setLayoutManager(new LinearLayoutManager(getContext()));
+            usersList.addItemDecoration(new SimpleListItemDividerDecoration(getContext()));
             noList.setVisibility(View.GONE);
-            FileDetailSharingFragmentHelper.setListViewHeightBasedOnChildren(usersList);
         } else {
             usersList.setVisibility(View.GONE);
             noList.setVisibility(View.VISIBLE);

+ 0 - 1
src/main/java/com/owncloud/android/ui/fragment/ShareFileFragment.java

@@ -653,7 +653,6 @@ public class ShareFileFragment extends Fragment implements ShareUserListAdapter.
             noShares.setVisibility(View.GONE);
             usersList.setVisibility(View.VISIBLE);
             usersList.setAdapter(mUserGroupsAdapter);
-            FileDetailSharingFragmentHelper.setListViewHeightBasedOnChildren(usersList);
         } else {
             noShares.setVisibility(View.VISIBLE);
             usersList.setVisibility(View.GONE);

+ 0 - 29
src/main/java/com/owncloud/android/ui/fragment/util/FileDetailSharingFragmentHelper.java

@@ -25,11 +25,7 @@ import android.content.ComponentName;
 import android.content.res.Resources;
 import android.support.v7.widget.SearchView;
 import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
 import android.view.inputmethod.EditorInfo;
-import android.widget.ListAdapter;
-import android.widget.ListView;
 
 import com.owncloud.android.R;
 import com.owncloud.android.lib.resources.shares.OCShare;
@@ -122,29 +118,4 @@ public class FileDetailSharingFragmentHelper {
     public static boolean isPublicShareDisabled(OCCapability capabilities) {
         return (capabilities != null && capabilities.getFilesSharingPublicEnabled().isFalse());
     }
-
-    /**
-     * Fix scroll in ListView when the parent is a ScrollView
-     */
-    public static void setListViewHeightBasedOnChildren(ListView listView) {
-        ListAdapter listAdapter = listView.getAdapter();
-        if (listAdapter == null) {
-            return;
-        }
-        int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(), View.MeasureSpec.AT_MOST);
-        int totalHeight = 0;
-        View view = null;
-        for (int i = 0; i < listAdapter.getCount(); i++) {
-            view = listAdapter.getView(i, view, listView);
-            if (i == 0) {
-                view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth, ViewGroup.LayoutParams.WRAP_CONTENT));
-            }
-            view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
-            totalHeight += view.getMeasuredHeight();
-        }
-        ViewGroup.LayoutParams params = listView.getLayoutParams();
-        params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
-        listView.setLayoutParams(params);
-        listView.requestLayout();
-    }
 }

+ 27 - 18
src/main/res/layout/file_details_share_user_item.xml

@@ -29,38 +29,47 @@
             android:id="@+id/userIcon"
             android:layout_width="@dimen/user_icon_size"
             android:layout_height="@dimen/user_icon_size"
-            android:src="@drawable/ic_user"
             android:layout_gravity="center_vertical"
-            android:layout_marginTop="@dimen/standard_half_margin"
             android:layout_marginBottom="@dimen/standard_half_margin"
-            android:layout_marginLeft="@dimen/standard_margin"
-            android:layout_marginStart="@dimen/standard_margin"
             android:layout_marginEnd="@dimen/standard_margin"
+            android:layout_marginLeft="@dimen/standard_margin"
             android:layout_marginRight="@dimen/standard_margin"
-            android:contentDescription="@string/user_icon"/>
+            android:layout_marginStart="@dimen/standard_margin"
+            android:layout_marginTop="@dimen/standard_half_margin"
+            android:contentDescription="@string/user_icon"
+            android:src="@drawable/ic_user" />
 
         <TextView
+            android:id="@+id/userOrGroupName"
             android:layout_width="0dp"
             android:layout_height="match_parent"
+            android:layout_marginEnd="@dimen/standard_quarter_margin"
+            android:layout_marginRight="@dimen/standard_quarter_margin"
             android:layout_weight="1"
-            android:textSize="@dimen/file_details_username_text_size"
-            android:text="@string/username"
-            android:id="@+id/userOrGroupName"
-            android:layout_marginRight="@dimen/standard_margin"
-            android:layout_marginEnd="@dimen/standard_margin"
-            android:singleLine="true"
-            android:ellipsize="middle"
+            android:ellipsize="end"
             android:gravity="center_vertical"
-            android:textColor="@color/black"/>
+            android:singleLine="true"
+            android:text="@string/username"
+            android:textColor="@color/black"
+            android:textSize="@dimen/file_details_username_text_size" />
 
-        <ImageView
+        <android.support.v7.widget.AppCompatCheckBox
+            android:id="@+id/allow_editing"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:text="@string/share_via_link_edit_permission_label" />
+
+        <ImageView
             android:id="@+id/editShareButton"
-            android:src="@drawable/ic_dots_vertical"
-            android:padding="@dimen/standard_half_padding"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:layout_marginLeft="@dimen/standard_half_margin"
+            android:layout_marginStart="@dimen/standard_half_margin"
             android:layout_marginEnd="@dimen/standard_half_margin"
             android:layout_marginRight="@dimen/standard_half_margin"
-            android:layout_gravity="center_vertical"
-            android:contentDescription="@string/overflow_menu"/>
+            android:contentDescription="@string/overflow_menu"
+            android:padding="@dimen/standard_half_padding"
+            android:src="@drawable/ic_dots_vertical" />
 </LinearLayout>

+ 2 - 3
src/main/res/layout/file_details_sharing_fragment.xml

@@ -90,12 +90,11 @@
                 android:src="@drawable/ic_dots_vertical" />
         </LinearLayout>
 
-        <ListView
+        <android.support.v7.widget.RecyclerView
             android:id="@+id/fdshareUsersList"
             android:layout_width="match_parent"
-            android:layout_height="0dip"
+            android:layout_height="0dp"
             android:layout_weight="1"
-            android:visibility="gone"
             android:divider="@drawable/divider"
             android:dividerHeight="1dp"/>
 

+ 0 - 6
src/main/res/menu/file_detail_sharing_menu.xml

@@ -22,12 +22,6 @@
     xmlns:tools="http://schemas.android.com/tools"
     tools:ignore="AppCompatResource">
 
-    <item
-        android:id="@+id/action_can_edit"
-        android:checkable="true"
-        android:showAsAction="never"
-        android:title="@string/share_privilege_can_edit"
-        app:showAsAction="never" />
     <item
         android:id="@+id/action_can_edit_create"
         android:checkable="true"