implement navigation drawer
This commit is contained in:
@@ -1,186 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* 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.sufficientlysecure.keychain.ui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
/**
|
||||
* Custom layout that arranges children in a grid-like manner, optimizing for even horizontal and
|
||||
* vertical whitespace.
|
||||
*/
|
||||
public class DashboardLayout extends ViewGroup {
|
||||
private static final int UNEVEN_GRID_PENALTY_MULTIPLIER = 10;
|
||||
|
||||
private int mMaxChildWidth = 0;
|
||||
private int mMaxChildHeight = 0;
|
||||
|
||||
public DashboardLayout(Context context) {
|
||||
super(context, null);
|
||||
}
|
||||
|
||||
public DashboardLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs, 0);
|
||||
}
|
||||
|
||||
public DashboardLayout(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
mMaxChildWidth = 0;
|
||||
mMaxChildHeight = 0;
|
||||
|
||||
// Measure once to find the maximum child size.
|
||||
|
||||
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
|
||||
MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.AT_MOST);
|
||||
int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
|
||||
MeasureSpec.getSize(heightMeasureSpec), MeasureSpec.AT_MOST);
|
||||
|
||||
final int count = getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View child = getChildAt(i);
|
||||
if (child.getVisibility() == GONE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
|
||||
|
||||
mMaxChildWidth = Math.max(mMaxChildWidth, child.getMeasuredWidth());
|
||||
mMaxChildHeight = Math.max(mMaxChildHeight, child.getMeasuredHeight());
|
||||
}
|
||||
|
||||
// Measure again for each child to be exactly the same size.
|
||||
|
||||
childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(mMaxChildWidth, MeasureSpec.EXACTLY);
|
||||
childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(mMaxChildHeight, MeasureSpec.EXACTLY);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View child = getChildAt(i);
|
||||
if (child.getVisibility() == GONE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
|
||||
}
|
||||
|
||||
setMeasuredDimension(resolveSize(mMaxChildWidth, widthMeasureSpec),
|
||||
resolveSize(mMaxChildHeight, heightMeasureSpec));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
int width = r - l;
|
||||
int height = b - t;
|
||||
|
||||
final int count = getChildCount();
|
||||
|
||||
// Calculate the number of visible children.
|
||||
int visibleCount = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View child = getChildAt(i);
|
||||
if (child.getVisibility() == GONE) {
|
||||
continue;
|
||||
}
|
||||
++visibleCount;
|
||||
}
|
||||
|
||||
if (visibleCount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate what number of rows and columns will optimize for even horizontal and
|
||||
// vertical whitespace between items. Start with a 1 x N grid, then try 2 x N, and so on.
|
||||
int bestSpaceDifference = Integer.MAX_VALUE;
|
||||
int spaceDifference;
|
||||
|
||||
// Horizontal and vertical space between items
|
||||
int hSpace = 0;
|
||||
int vSpace = 0;
|
||||
|
||||
int cols = 1;
|
||||
int rows;
|
||||
|
||||
while (true) {
|
||||
rows = (visibleCount - 1) / cols + 1;
|
||||
|
||||
hSpace = ((width - mMaxChildWidth * cols) / (cols + 1));
|
||||
vSpace = ((height - mMaxChildHeight * rows) / (rows + 1));
|
||||
|
||||
spaceDifference = Math.abs(vSpace - hSpace);
|
||||
if (rows * cols != visibleCount) {
|
||||
spaceDifference *= UNEVEN_GRID_PENALTY_MULTIPLIER;
|
||||
} else if (rows * mMaxChildHeight > height || cols * mMaxChildWidth > width) {
|
||||
spaceDifference *= UNEVEN_GRID_PENALTY_MULTIPLIER;
|
||||
}
|
||||
|
||||
if (spaceDifference < bestSpaceDifference) {
|
||||
// Found a better whitespace squareness/ratio
|
||||
bestSpaceDifference = spaceDifference;
|
||||
|
||||
// If we found a better whitespace squareness and there's only 1 row, this is
|
||||
// the best we can do.
|
||||
if (rows == 1) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// This is a worse whitespace ratio, use the previous value of cols and exit.
|
||||
--cols;
|
||||
rows = (visibleCount - 1) / cols + 1;
|
||||
hSpace = ((width - mMaxChildWidth * cols) / (cols + 1));
|
||||
vSpace = ((height - mMaxChildHeight * rows) / (rows + 1));
|
||||
break;
|
||||
}
|
||||
|
||||
++cols;
|
||||
}
|
||||
|
||||
// Lay out children based on calculated best-fit number of rows and cols.
|
||||
|
||||
// If we chose a layout that has negative horizontal or vertical space, force it to zero.
|
||||
hSpace = Math.max(0, hSpace);
|
||||
vSpace = Math.max(0, vSpace);
|
||||
|
||||
// Re-use width/height variables to be child width/height.
|
||||
width = (width - hSpace * (cols + 1)) / cols;
|
||||
height = (height - vSpace * (rows + 1)) / rows;
|
||||
|
||||
int left, top;
|
||||
int col, row;
|
||||
int visibleIndex = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View child = getChildAt(i);
|
||||
if (child.getVisibility() == GONE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
row = visibleIndex / cols;
|
||||
col = visibleIndex % cols;
|
||||
|
||||
left = hSpace * (col + 1) + width * col;
|
||||
top = vSpace * (row + 1) + height * row;
|
||||
|
||||
child.layout(left, top, (hSpace == 0 && col == cols - 1) ? r : (left + width),
|
||||
(vSpace == 0 && row == rows - 1) ? b : (top + height));
|
||||
++visibleIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user