diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/BoardSetupController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/BoardSetupController.java index 640e557a..489a2d39 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/BoardSetupController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/BoardSetupController.java @@ -28,6 +28,7 @@ import android.support.v7.app.AlertDialog; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.helper.ItemTouchHelper; +import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; @@ -44,13 +45,16 @@ import org.floens.chan.core.presenter.BoardSetupPresenter; import org.floens.chan.core.site.Site; import org.floens.chan.ui.helper.BoardHelper; import org.floens.chan.ui.layout.BoardAddLayout; +import org.floens.chan.ui.view.DividerItemDecoration; import java.util.List; import javax.inject.Inject; +import static android.text.TextUtils.isEmpty; import static org.floens.chan.Chan.inject; import static org.floens.chan.ui.theme.ThemeHelper.theme; +import static org.floens.chan.utils.AndroidUtils.dp; import static org.floens.chan.utils.AndroidUtils.fixSnackbarText; import static org.floens.chan.utils.AndroidUtils.getAttrColor; @@ -117,6 +121,8 @@ public class BoardSetupController extends Controller implements View.OnClickList // View setup savedBoardsRecycler.setLayoutManager(new LinearLayoutManager(context)); savedBoardsRecycler.setAdapter(savedAdapter); + savedBoardsRecycler.addItemDecoration( + new DividerItemDecoration(context, DividerItemDecoration.VERTICAL)); itemTouchHelper = new ItemTouchHelper(touchHelperCallback); itemTouchHelper.attachToRecyclerView(savedBoardsRecycler); add.setOnClickListener(this); @@ -222,7 +228,25 @@ public class BoardSetupController extends Controller implements View.OnClickList public void onBindViewHolder(SavedBoardCell holder, int position) { Board savedBoard = savedBoards.get(position); holder.text.setText(BoardHelper.getName(savedBoard)); - holder.description.setText(savedBoard.order + " - " + BoardHelper.getDescription(savedBoard)); + String description = BoardHelper.getDescription(savedBoard); + boolean enableDescription = !isEmpty(description); + if (enableDescription) { + holder.description.setVisibility(View.VISIBLE); + holder.description.setText(description); + } else { + holder.description.setVisibility(View.GONE); + } + + // Fill the height for the title if there is no description, otherwise make room + // for it. + ViewGroup.LayoutParams p = holder.text.getLayoutParams(); + int newHeight = enableDescription ? dp(28) : dp(56); + if (newHeight != p.height) { + p.height = newHeight; + holder.text.setLayoutParams(p); + } + holder.text.setGravity(Gravity.CENTER_VERTICAL); + holder.text.setPadding(dp(8), dp(8), dp(8), enableDescription ? 0 : dp(8)); } @Override diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/SitesSetupController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/SitesSetupController.java index 02dd35ac..d2a215b2 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/SitesSetupController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/SitesSetupController.java @@ -40,6 +40,7 @@ import org.floens.chan.ui.helper.HintPopup; import org.floens.chan.ui.layout.SiteAddLayout; import org.floens.chan.ui.toolbar.ToolbarMenu; import org.floens.chan.ui.toolbar.ToolbarMenuItem; +import org.floens.chan.ui.view.DividerItemDecoration; import org.floens.chan.ui.view.FloatingMenuItem; import java.util.ArrayList; @@ -90,6 +91,8 @@ public class SitesSetupController extends StyledToolbarNavigationController impl // View setup sitesRecyclerview.setLayoutManager(new LinearLayoutManager(context)); sitesRecyclerview.setAdapter(sitesAdapter); + sitesRecyclerview.addItemDecoration( + new DividerItemDecoration(context, DividerItemDecoration.VERTICAL)); addButton.setOnClickListener(this); theme().applyFabColor(addButton); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/view/DividerItemDecoration.java b/Clover/app/src/main/java/org/floens/chan/ui/view/DividerItemDecoration.java new file mode 100644 index 00000000..acce08a0 --- /dev/null +++ b/Clover/app/src/main/java/org/floens/chan/ui/view/DividerItemDecoration.java @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.floens.chan.ui.view; + +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.annotation.NonNull; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.View; +import android.widget.LinearLayout; + +/** + * DividerItemDecoration is a {@link RecyclerView.ItemDecoration} that can be used as a divider + * between items of a {@link LinearLayoutManager}. It supports both {@link #HORIZONTAL} and + * {@link #VERTICAL} orientations. + * + *
+ *     mDividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
+ *             mLayoutManager.getOrientation());
+ *     recyclerView.addItemDecoration(mDividerItemDecoration);
+ * 
+ */ +public class DividerItemDecoration extends RecyclerView.ItemDecoration { + public static final int HORIZONTAL = LinearLayout.HORIZONTAL; + public static final int VERTICAL = LinearLayout.VERTICAL; + + private static final String TAG = "DividerItem"; + private static final int[] ATTRS = new int[]{ android.R.attr.listDivider }; + + private Drawable mDivider; + + /** + * Current orientation. Either {@link #HORIZONTAL} or {@link #VERTICAL}. + */ + private int mOrientation; + + private final Rect mBounds = new Rect(); + + /** + * Creates a divider {@link RecyclerView.ItemDecoration} that can be used with a + * {@link LinearLayoutManager}. + * + * @param context Current context, it will be used to access resources. + * @param orientation Divider orientation. Should be {@link #HORIZONTAL} or {@link #VERTICAL}. + */ + public DividerItemDecoration(Context context, int orientation) { + final TypedArray a = context.obtainStyledAttributes(ATTRS); + mDivider = a.getDrawable(0); + if (mDivider == null) { + Log.w(TAG, "@android:attr/listDivider was not set in the theme used for this " + + "DividerItemDecoration. Please set that attribute all call setDrawable()"); + } + a.recycle(); + setOrientation(orientation); + } + + /** + * Sets the orientation for this divider. This should be called if + * {@link RecyclerView.LayoutManager} changes orientation. + * + * @param orientation {@link #HORIZONTAL} or {@link #VERTICAL} + */ + public void setOrientation(int orientation) { + if (orientation != HORIZONTAL && orientation != VERTICAL) { + throw new IllegalArgumentException( + "Invalid orientation. It should be either HORIZONTAL or VERTICAL"); + } + mOrientation = orientation; + } + + /** + * Sets the {@link Drawable} for this divider. + * + * @param drawable Drawable that should be used as a divider. + */ + public void setDrawable(@NonNull Drawable drawable) { + if (drawable == null) { + throw new IllegalArgumentException("Drawable cannot be null."); + } + mDivider = drawable; + } + + @Override + public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { + if (parent.getLayoutManager() == null || mDivider == null) { + return; + } + if (mOrientation == VERTICAL) { + drawVertical(c, parent); + } else { + drawHorizontal(c, parent); + } + } + + private void drawVertical(Canvas canvas, RecyclerView parent) { + canvas.save(); + final int left; + final int right; + //noinspection AndroidLintNewApi - NewApi lint fails to handle overrides. + // Clover changed: still apply insets even when it's not set to clipPadding, plus don't + // clip the top and bottom. + left = parent.getPaddingLeft(); + right = parent.getWidth() - parent.getPaddingRight(); + canvas.clipRect(left, 0, right, parent.getHeight()); + + final int childCount = parent.getChildCount(); + for (int i = 0; i < childCount; i++) { + final View child = parent.getChildAt(i); + parent.getDecoratedBoundsWithMargins(child, mBounds); + final int bottom = mBounds.bottom + Math.round(child.getTranslationY()); + final int top = bottom - mDivider.getIntrinsicHeight(); + mDivider.setBounds(left, top, right, bottom); + mDivider.draw(canvas); + } + canvas.restore(); + } + + private void drawHorizontal(Canvas canvas, RecyclerView parent) { + canvas.save(); + final int top; + final int bottom; + //noinspection AndroidLintNewApi - NewApi lint fails to handle overrides. + if (parent.getClipToPadding()) { + top = parent.getPaddingTop(); + bottom = parent.getHeight() - parent.getPaddingBottom(); + canvas.clipRect(parent.getPaddingLeft(), top, + parent.getWidth() - parent.getPaddingRight(), bottom); + } else { + top = 0; + bottom = parent.getHeight(); + } + + final int childCount = parent.getChildCount(); + for (int i = 0; i < childCount; i++) { + final View child = parent.getChildAt(i); + parent.getLayoutManager().getDecoratedBoundsWithMargins(child, mBounds); + final int right = mBounds.right + Math.round(child.getTranslationX()); + final int left = right - mDivider.getIntrinsicWidth(); + mDivider.setBounds(left, top, right, bottom); + mDivider.draw(canvas); + } + canvas.restore(); + } + + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, + RecyclerView.State state) { + if (mDivider == null) { + outRect.set(0, 0, 0, 0); + return; + } + if (mOrientation == VERTICAL) { + outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); + } else { + outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); + } + } +} diff --git a/Clover/app/src/main/res/layout/cell_board.xml b/Clover/app/src/main/res/layout/cell_board.xml index 2c7e3977..273a9682 100644 --- a/Clover/app/src/main/res/layout/cell_board.xml +++ b/Clover/app/src/main/res/layout/cell_board.xml @@ -20,9 +20,8 @@ along with this program. If not, see . android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/backcolor" - android:orientation="horizontal" - android:paddingLeft="8dp" - android:paddingRight="8dp"> + android:minHeight="56dp" + android:orientation="horizontal"> . . android:id="@+id/description" android:layout_width="match_parent" android:layout_height="wrap_content" - android:ellipsize="end" android:paddingBottom="8dp" + android:paddingLeft="8dp" + android:paddingRight="8dp" android:textColor="?text_color_secondary" android:textSize="12sp" tools:text="Description is here" /> @@ -55,10 +57,10 @@ along with this program. If not, see . diff --git a/Clover/app/src/main/res/layout/cell_site.xml b/Clover/app/src/main/res/layout/cell_site.xml index 510f59b0..fc9102ea 100644 --- a/Clover/app/src/main/res/layout/cell_site.xml +++ b/Clover/app/src/main/res/layout/cell_site.xml @@ -18,31 +18,31 @@ along with this program. If not, see . . @@ -66,11 +66,9 @@ along with this program. If not, see . diff --git a/Clover/app/src/main/res/layout/controller_board_setup.xml b/Clover/app/src/main/res/layout/controller_board_setup.xml index 8aa51b9c..73c6ee0c 100644 --- a/Clover/app/src/main/res/layout/controller_board_setup.xml +++ b/Clover/app/src/main/res/layout/controller_board_setup.xml @@ -24,9 +24,8 @@ along with this program. If not, see . android:id="@+id/boards_recycler" android:layout_width="match_parent" android:layout_height="match_parent" - android:clipChildren="false" android:clipToPadding="false" - android:paddingBottom="80dp" + android:paddingBottom="88dp" android:paddingLeft="8dp" android:paddingRight="8dp" android:paddingTop="8dp" diff --git a/Clover/app/src/main/res/layout/controller_sites_setup.xml b/Clover/app/src/main/res/layout/controller_sites_setup.xml index 23d6da77..d1a188ad 100644 --- a/Clover/app/src/main/res/layout/controller_sites_setup.xml +++ b/Clover/app/src/main/res/layout/controller_sites_setup.xml @@ -16,11 +16,9 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . --> @@ -28,8 +26,11 @@ along with this program. If not, see . android:id="@+id/sites_recycler" android:layout_width="match_parent" android:layout_height="match_parent" - android:padding="16dp" + android:clipToPadding="false" android:paddingBottom="72dp" + android:paddingLeft="8dp" + android:paddingRight="8dp" + android:paddingTop="8dp" android:scrollbarStyle="outsideOverlay" android:scrollbars="vertical" />