瀏覽代碼

Merge pull request #7052 from nextcloud/resourceFix

streamline layout for user infos
Andy Scherzinger 4 年之前
父節點
當前提交
5ebd4b007c

二進制
screenshots/gplay/debug/com.owncloud.android.ui.activity.ManageAccountsActivityIT_userInfoDetail.png


二進制
screenshots/gplay/debug/com.owncloud.android.ui.activity.UserInfoActivityIT_fullUserInfoDetail.png


+ 1 - 1
scripts/analysis/findbugs-results.txt

@@ -1 +1 @@
-319
+318

+ 1 - 1
scripts/analysis/lint-results.txt

@@ -1,2 +1,2 @@
 DO NOT TOUCH; GENERATED BY DRONE
-      <span class="mdl-layout-title">Lint Report: 356 warnings</span>
+      <span class="mdl-layout-title">Lint Report: 346 warnings</span>

+ 65 - 0
src/androidTest/java/com/owncloud/android/ui/activity/UserInfoActivityIT.java

@@ -0,0 +1,65 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Andy Scherzinger
+ * Copyright (C) 2020 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 as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) 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 <https://www.gnu.org/licenses/>.
+ */
+
+package com.owncloud.android.ui.activity;
+
+import android.content.Intent;
+
+import com.owncloud.android.AbstractIT;
+import com.owncloud.android.lib.common.UserInfo;
+import com.owncloud.android.utils.ScreenshotTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.parceler.Parcels;
+
+import androidx.test.espresso.intent.rule.IntentsTestRule;
+
+public class UserInfoActivityIT extends AbstractIT {
+    @Rule
+    public IntentsTestRule<UserInfoActivity> activityRule = new IntentsTestRule<>(UserInfoActivity.class,
+                                                                                  true,
+                                                                                  false);
+
+    @Test
+    @ScreenshotTest
+    public void fullUserInfoDetail() {
+        final Intent intent = new Intent(targetContext, UserInfoActivity.class);
+        intent.putExtra(UserInfoActivity.KEY_ACCOUNT, user);
+        UserInfo userInfo = new UserInfo("test",
+                                         true,
+                                         "Firstname Familyname",
+                                         "oss@rocks.com",
+                                         "+49 7613 672 255",
+                                         "Awesome Place Av.",
+                                         "https://www.nextcloud.com",
+                                         "nextclouders",
+                                         null,
+                                         null
+        );
+        intent.putExtra(UserInfoActivity.KEY_USER_DATA, Parcels.wrap(userInfo));
+        UserInfoActivity sut = activityRule.launchActivity(intent);
+
+        shortSleep();
+        shortSleep();
+
+        screenshot(sut);
+    }
+}

+ 47 - 63
src/main/java/com/owncloud/android/ui/activity/UserInfoActivity.java

@@ -41,8 +41,6 @@ import android.view.View;
 import android.view.ViewGroup;
 import android.webkit.URLUtil;
 import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.ProgressBar;
 import android.widget.TextView;
 
 import com.bumptech.glide.Glide;
@@ -52,6 +50,7 @@ import com.nextcloud.client.account.User;
 import com.nextcloud.client.di.Injectable;
 import com.nextcloud.client.preferences.AppPreferences;
 import com.owncloud.android.R;
+import com.owncloud.android.databinding.UserInfoLayoutBinding;
 import com.owncloud.android.lib.common.UserInfo;
 import com.owncloud.android.lib.common.operations.RemoteOperation;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
@@ -82,10 +81,8 @@ import androidx.core.graphics.drawable.DrawableCompat;
 import androidx.fragment.app.FragmentManager;
 import androidx.lifecycle.Lifecycle;
 import androidx.recyclerview.widget.RecyclerView;
-import butterknife.BindString;
 import butterknife.BindView;
 import butterknife.ButterKnife;
-import butterknife.Unbinder;
 
 /**
  * This Activity presents the user information.
@@ -94,27 +91,14 @@ public class UserInfoActivity extends DrawerActivity implements Injectable {
     public static final String KEY_ACCOUNT = "ACCOUNT";
 
     private static final String TAG = UserInfoActivity.class.getSimpleName();
-    private static final String KEY_USER_DATA = "USER_DATA";
-
-    @BindView(R.id.empty_list_view) protected LinearLayout emptyContentContainer;
-    @BindView(R.id.empty_list_view_text) protected TextView emptyContentMessage;
-    @BindView(R.id.empty_list_view_headline) protected TextView emptyContentHeadline;
-    @BindView(R.id.empty_list_icon) protected ImageView emptyContentIcon;
-    @BindView(R.id.userinfo_icon) protected ImageView avatar;
-    @BindView(R.id.userinfo_username) protected TextView userName;
-    @BindView(R.id.userinfo_fullName) protected TextView fullName;
-    @BindView(R.id.userinfo_list) protected RecyclerView mUserInfoList;
-    @BindView(R.id.empty_list_progress) protected ProgressBar multiListProgressBar;
-
-    @BindString(R.string.user_information_retrieval_error) protected String sorryMessage;
+    public static final String KEY_USER_DATA = "USER_DATA";
 
     @Inject AppPreferences preferences;
     private float mCurrentAccountAvatarRadiusDimension;
 
-    private Unbinder unbinder;
-
     private UserInfo userInfo;
     private User user;
+    private UserInfoLayoutBinding binding;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -135,12 +119,14 @@ public class UserInfoActivity extends DrawerActivity implements Injectable {
 
         if (savedInstanceState != null && savedInstanceState.containsKey(KEY_USER_DATA)) {
             userInfo = Parcels.unwrap(savedInstanceState.getParcelable(KEY_USER_DATA));
+        } else if (bundle.containsKey(KEY_ACCOUNT)) {
+            userInfo = Parcels.unwrap(bundle.getParcelable(KEY_USER_DATA));
         }
 
-        mCurrentAccountAvatarRadiusDimension = getResources().getDimension(R.dimen.nav_drawer_header_avatar_radius);
+        mCurrentAccountAvatarRadiusDimension = getResources().getDimension(R.dimen.user_icon_radius);
 
-        setContentView(R.layout.user_info_layout);
-        unbinder = ButterKnife.bind(this);
+        binding = UserInfoLayoutBinding.inflate(getLayoutInflater());
+        setContentView(binding.getRoot());
 
         setupToolbar();
 
@@ -154,7 +140,7 @@ public class UserInfoActivity extends DrawerActivity implements Injectable {
             ThemeUtils.tintBackButton(actionBar, this);
         }
 
-        mUserInfoList.setAdapter(new UserInfoAdapter(null, ThemeUtils.primaryColor(getAccount(), true, this)));
+        binding.userinfoList.setAdapter(new UserInfoAdapter(null, ThemeUtils.primaryColor(getAccount(), true, this)));
 
         if (userInfo != null) {
             populateUserInfoUi(userInfo);
@@ -202,34 +188,25 @@ public class UserInfoActivity extends DrawerActivity implements Injectable {
         return retval;
     }
 
-    public void onDestroy() {
-        super.onDestroy();
-        unbinder.unbind();
-    }
-
     private void setMultiListLoadingMessage() {
-        if (emptyContentContainer != null) {
-            emptyContentHeadline.setText(R.string.file_list_loading);
-            emptyContentMessage.setText("");
-
-            emptyContentIcon.setVisibility(View.GONE);
-            emptyContentMessage.setVisibility(View.GONE);
-            multiListProgressBar.getIndeterminateDrawable().setColorFilter(ThemeUtils.primaryColor(this),
-                    PorterDuff.Mode.SRC_IN);
-            multiListProgressBar.setVisibility(View.VISIBLE);
-        }
+        binding.emptyList.emptyListViewHeadline.setText(R.string.file_list_loading);
+        binding.emptyList.emptyListViewText.setText("");
+
+        binding.emptyList.emptyListIcon.setVisibility(View.GONE);
+        binding.emptyList.emptyListViewText.setVisibility(View.GONE);
+        binding.emptyList.emptyListProgress.getIndeterminateDrawable().setColorFilter(ThemeUtils.primaryColor(this),
+                                                                                      PorterDuff.Mode.SRC_IN);
+        binding.emptyList.emptyListProgress.setVisibility(View.VISIBLE);
     }
 
     private void setErrorMessageForMultiList(String headline, String message, @DrawableRes int errorResource) {
-        if (emptyContentContainer != null && emptyContentMessage != null) {
-            emptyContentHeadline.setText(headline);
-            emptyContentMessage.setText(message);
-            emptyContentIcon.setImageResource(errorResource);
-
-            multiListProgressBar.setVisibility(View.GONE);
-            emptyContentIcon.setVisibility(View.VISIBLE);
-            emptyContentMessage.setVisibility(View.VISIBLE);
-        }
+        binding.emptyList.emptyListViewHeadline.setText(headline);
+        binding.emptyList.emptyListViewText.setText(message);
+        binding.emptyList.emptyListIcon.setImageResource(errorResource);
+
+        binding.emptyList.emptyListProgress.setVisibility(View.GONE);
+        binding.emptyList.emptyListIcon.setVisibility(View.VISIBLE);
+        binding.emptyList.emptyListViewText.setVisibility(View.VISIBLE);
     }
 
     private void setHeaderImage() {
@@ -278,27 +255,32 @@ public class UserInfoActivity extends DrawerActivity implements Injectable {
     }
 
     private void populateUserInfoUi(UserInfo userInfo) {
-        userName.setText(user.getAccountName());
-        avatar.setTag(user.getAccountName());
-        DisplayUtils.setAvatar(user, this, mCurrentAccountAvatarRadiusDimension, getResources(), avatar, this);
+        binding.userinfoUsername.setText(user.getAccountName());
+        binding.userinfoIcon.setTag(user.getAccountName());
+        DisplayUtils.setAvatar(user,
+                               this,
+                               mCurrentAccountAvatarRadiusDimension,
+                               getResources(),
+                               binding.userinfoIcon,
+                               this);
 
         int tint = ThemeUtils.primaryColor(user.toPlatformAccount(), true, this);
 
         if (!TextUtils.isEmpty(userInfo.getDisplayName())) {
-            fullName.setText(userInfo.getDisplayName());
+            binding.userinfoFullName.setText(userInfo.getDisplayName());
         }
 
         if (userInfo.getPhone() == null && userInfo.getEmail() == null && userInfo.getAddress() == null
-                && userInfo.getTwitter() == null && userInfo.getWebsite() == null) {
+            && userInfo.getTwitter() == null && userInfo.getWebsite() == null) {
 
             setErrorMessageForMultiList(getString(R.string.userinfo_no_info_headline),
-                getString(R.string.userinfo_no_info_text), R.drawable.ic_user);
+                                        getString(R.string.userinfo_no_info_text), R.drawable.ic_user);
         } else {
-            emptyContentContainer.setVisibility(View.GONE);
-            mUserInfoList.setVisibility(View.VISIBLE);
+            binding.emptyList.emptyListView.setVisibility(View.GONE);
+            binding.userinfoList.setVisibility(View.VISIBLE);
 
-            if (mUserInfoList.getAdapter() instanceof UserInfoAdapter) {
-                mUserInfoList.setAdapter(new UserInfoAdapter(createUserInfoDetails(userInfo), tint));
+            if (binding.userinfoList.getAdapter() instanceof UserInfoAdapter) {
+                binding.userinfoList.setAdapter(new UserInfoAdapter(createUserInfoDetails(userInfo), tint));
             }
         }
     }
@@ -343,9 +325,11 @@ public class UserInfoActivity extends DrawerActivity implements Injectable {
                     runOnUiThread(() -> populateUserInfoUi(userInfo));
                 } else {
                     // show error
-                    runOnUiThread(() -> setErrorMessageForMultiList(sorryMessage,
-                                                                    result.getLogMessage(),
-                                                                    R.drawable.ic_list_empty_error));
+                    runOnUiThread(() -> setErrorMessageForMultiList(
+                        getString(R.string.user_information_retrieval_error),
+                        result.getLogMessage(),
+                        R.drawable.ic_list_empty_error)
+                                 );
                     Log_OC.d(TAG, result.getLogMessage());
                 }
             }
@@ -368,7 +352,7 @@ public class UserInfoActivity extends DrawerActivity implements Injectable {
     }
 
 
-    protected class UserInfoDetailsItem {
+    protected static class UserInfoDetailsItem {
         @DrawableRes public int icon;
         public String text;
         public String iconContentDescription;
@@ -380,11 +364,11 @@ public class UserInfoActivity extends DrawerActivity implements Injectable {
         }
     }
 
-    protected class UserInfoAdapter extends RecyclerView.Adapter<UserInfoAdapter.ViewHolder> {
+    protected static class UserInfoAdapter extends RecyclerView.Adapter<UserInfoAdapter.ViewHolder> {
         protected List<UserInfoDetailsItem> mDisplayList;
         @ColorInt protected int mTintColor;
 
-        public class ViewHolder extends RecyclerView.ViewHolder {
+        public static class ViewHolder extends RecyclerView.ViewHolder {
 
             @BindView(R.id.icon) protected ImageView icon;
             @BindView(R.id.text) protected TextView text;

+ 6 - 6
src/main/res/layout/user_info_details_table_item.xml

@@ -21,15 +21,14 @@
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:layout_marginTop="12dp"
-    android:layout_marginBottom="12dp"
+    android:layout_height="@dimen/iconized_single_line_item_layout_height"
     android:orientation="horizontal">
 
     <ImageView
         android:id="@+id/icon"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
+        android:layout_width="@dimen/iconized_single_line_item_icon_size"
+        android:layout_height="@dimen/iconized_single_line_item_icon_size"
+        android:layout_marginStart="@dimen/user_info_icon_horizontal_margin"
         android:contentDescription="@string/account_icon"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintStart_toStartOf="parent"
@@ -40,7 +39,8 @@
         android:id="@+id/text"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
-        android:layout_marginStart="@dimen/standard_icon_list_horizontal_margin"
+        android:layout_marginStart="@dimen/user_info_icon_horizontal_margin"
+        android:layout_marginEnd="@dimen/standard_margin"
         android:ellipsize="end"
         android:maxLines="3"
         android:textAppearance="?android:attr/textAppearanceListItem"

+ 14 - 11
src/main/res/layout/user_info_layout.xml

@@ -40,15 +40,16 @@
             android:scaleType="centerCrop"
             app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintHorizontal_bias="0.0"
             app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toTopOf="parent" />
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.0" />
 
         <ImageView
             android:id="@+id/userinfo_icon"
-            android:layout_width="@dimen/nav_drawer_header_avatar"
-            android:layout_height="@dimen/nav_drawer_header_avatar"
-            android:layout_marginStart="@dimen/account_item_layout_user_image_left_start_margin"
-            android:layout_marginBottom="@dimen/account_item_layout_user_image_left_start_margin"
+            android:layout_width="@dimen/user_icon_size"
+            android:layout_height="@dimen/user_icon_size"
+            android:layout_margin="@dimen/standard_margin"
             android:contentDescription="@string/avatar"
             android:src="@drawable/account_circle_white"
             app:layout_constraintBottom_toBottomOf="parent"
@@ -58,8 +59,8 @@
             android:id="@+id/userinfo_fullName"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
-            android:layout_marginStart="8dp"
-            android:layout_marginTop="8dp"
+            android:layout_marginStart="@dimen/standard_margin"
+            android:layout_marginEnd="@dimen/standard_margin"
             android:ellipsize="end"
             android:lines="1"
             android:shadowColor="@color/drawer_shadow"
@@ -78,6 +79,7 @@
             android:id="@+id/userinfo_username"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
+            android:layout_marginEnd="@dimen/standard_margin"
             android:ellipsize="end"
             android:lines="2"
             android:shadowColor="@color/drawer_shadow"
@@ -97,14 +99,15 @@
         android:id="@+id/userinfo_list"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:layout_margin="@dimen/standard_margin"
         android:orientation="vertical"
         android:visibility="gone"
         app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
-        tools:visibility="visible"
+        tools:itemCount="3"
         tools:listitem="@layout/user_info_details_table_item"
-        tools:itemCount="3" />
+        tools:visibility="visible" />
 
-    <include layout="@layout/empty_list" />
+    <include
+        android:id="@+id/emptyList"
+        layout="@layout/empty_list" />
 
 </LinearLayout>

+ 0 - 5
src/main/res/values-sw360dp/dims.xml

@@ -17,10 +17,5 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 -->
 <resources>
-  <!-- Default screen margins, per the Android Design guidelines. -->
-  <dimen name="nav_drawer_header_height">164dp</dimen>
-  <dimen name="nav_drawer_header_avatar">64dp</dimen>
-  <!-- avatar radius needs to 1/2 of the avatar dp value -->
-  <dimen name="nav_drawer_header_avatar_radius">32dp</dimen>
   <integer name="media_grid_width">4</integer>
 </resources>

+ 4 - 3
src/main/res/values/dims.xml

@@ -17,8 +17,7 @@
 -->
 <resources>
     <!-- Default screen margins, per the Android Design guidelines. -->
-    <dimen name="nav_drawer_header_height">140dp</dimen>
-    <dimen name="nav_drawer_header_avatar">56dp</dimen>
+    <dimen name="nav_drawer_header_height">164dp</dimen>
     <dimen name="nav_drawer_menu_avatar_radius">12sp</dimen>
     <dimen name="list_item_avatar_icon_radius">20dp</dimen>
     <dimen name="bottom_sheet_menu_item_divider_standard_margin">56dp</dimen>
@@ -33,7 +32,6 @@
     <dimen name="standard_quarter_padding">4dp</dimen>
     <dimen name="standard_eight_padding">2dp</dimen>
     <dimen name="standard_margin">16dp</dimen>
-    <dimen name="standard_icon_list_horizontal_margin">24dp</dimen>
     <dimen name="standard_double_margin">32dp</dimen>
     <dimen name="standard_half_margin">8dp</dimen>
     <dimen name="standard_quarter_margin">4dp</dimen>
@@ -47,6 +45,9 @@
     <dimen name="file_list_item_avatar_icon_radius">10dp</dimen>
     <dimen name="account_action_layout_height">72dp</dimen>
     <dimen name="zero">0dp</dimen>
+    <dimen name="iconized_single_line_item_layout_height">56dp</dimen>
+    <dimen name="iconized_single_line_item_icon_size">24dp</dimen>
+    <dimen name="user_info_icon_horizontal_margin">24dp</dimen>
     <dimen name="account_item_layout_height">72dp</dimen>
     <dimen name="user_icon_size">40dp</dimen>
     <dimen name="user_icon_radius">20dp</dimen>