am ace33655: Merge "Improve GridLayout\'s weight calculations" into lmp-mr1-dev
* commit 'ace33655bff514698b322253c211f0af5a3edd37': Improve GridLayout's weight calculations
This commit is contained in:
@@ -1613,7 +1613,11 @@ public class GridLayout extends ViewGroup {
|
|||||||
equivalent to the single-source shortest paths problem on a digraph, for
|
equivalent to the single-source shortest paths problem on a digraph, for
|
||||||
which the O(n^2) Bellman-Ford algorithm the most commonly used general solution.
|
which the O(n^2) Bellman-Ford algorithm the most commonly used general solution.
|
||||||
*/
|
*/
|
||||||
private void solve(Arc[] arcs, int[] locations) {
|
private boolean solve(Arc[] arcs, int[] locations) {
|
||||||
|
return solve(arcs, locations, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean solve(Arc[] arcs, int[] locations, boolean modifyOnError) {
|
||||||
String axisName = horizontal ? "horizontal" : "vertical";
|
String axisName = horizontal ? "horizontal" : "vertical";
|
||||||
int N = getCount() + 1; // The number of vertices is the number of columns/rows + 1.
|
int N = getCount() + 1; // The number of vertices is the number of columns/rows + 1.
|
||||||
boolean[] originalCulprits = null;
|
boolean[] originalCulprits = null;
|
||||||
@@ -1631,10 +1635,14 @@ public class GridLayout extends ViewGroup {
|
|||||||
if (originalCulprits != null) {
|
if (originalCulprits != null) {
|
||||||
logError(axisName, arcs, originalCulprits);
|
logError(axisName, arcs, originalCulprits);
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!modifyOnError) {
|
||||||
|
return false; // cannot solve with these constraints
|
||||||
|
}
|
||||||
|
|
||||||
boolean[] culprits = new boolean[arcs.length];
|
boolean[] culprits = new boolean[arcs.length];
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
for (int j = 0, length = arcs.length; j < length; j++) {
|
for (int j = 0, length = arcs.length; j < length; j++) {
|
||||||
@@ -1658,6 +1666,7 @@ public class GridLayout extends ViewGroup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void computeMargins(boolean leading) {
|
private void computeMargins(boolean leading) {
|
||||||
@@ -1697,8 +1706,8 @@ public class GridLayout extends ViewGroup {
|
|||||||
return trailingMargins;
|
return trailingMargins;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void solve(int[] a) {
|
private boolean solve(int[] a) {
|
||||||
solve(getArcs(), a);
|
return solve(getArcs(), a);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean computeHasWeights() {
|
private boolean computeHasWeights() {
|
||||||
@@ -1740,28 +1749,18 @@ public class GridLayout extends ViewGroup {
|
|||||||
return deltas;
|
return deltas;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void shareOutDelta() {
|
private void shareOutDelta(int totalDelta, float totalWeight) {
|
||||||
int totalDelta = 0;
|
Arrays.fill(deltas, 0);
|
||||||
float totalWeight = 0;
|
|
||||||
for (int i = 0, N = getChildCount(); i < N; i++) {
|
for (int i = 0, N = getChildCount(); i < N; i++) {
|
||||||
View c = getChildAt(i);
|
View c = getChildAt(i);
|
||||||
LayoutParams lp = getLayoutParams(c);
|
LayoutParams lp = getLayoutParams(c);
|
||||||
Spec spec = horizontal ? lp.columnSpec : lp.rowSpec;
|
Spec spec = horizontal ? lp.columnSpec : lp.rowSpec;
|
||||||
float weight = spec.weight;
|
float weight = spec.weight;
|
||||||
if (weight != 0) {
|
|
||||||
int delta = getMeasurement(c, horizontal) - getOriginalMeasurements()[i];
|
|
||||||
totalDelta += delta;
|
|
||||||
totalWeight += weight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = 0, N = getChildCount(); i < N; i++) {
|
|
||||||
LayoutParams lp = getLayoutParams(getChildAt(i));
|
|
||||||
Spec spec = horizontal ? lp.columnSpec : lp.rowSpec;
|
|
||||||
float weight = spec.weight;
|
|
||||||
if (weight != 0) {
|
if (weight != 0) {
|
||||||
int delta = Math.round((weight * totalDelta / totalWeight));
|
int delta = Math.round((weight * totalDelta / totalWeight));
|
||||||
deltas[i] = delta;
|
deltas[i] = delta;
|
||||||
// the two adjustments below are to counter the above rounding and avoid off-by-ones at the end
|
// the two adjustments below are to counter the above rounding and avoid
|
||||||
|
// off-by-ones at the end
|
||||||
totalDelta -= delta;
|
totalDelta -= delta;
|
||||||
totalWeight -= weight;
|
totalWeight -= weight;
|
||||||
}
|
}
|
||||||
@@ -1771,13 +1770,47 @@ public class GridLayout extends ViewGroup {
|
|||||||
private void solveAndDistributeSpace(int[] a) {
|
private void solveAndDistributeSpace(int[] a) {
|
||||||
Arrays.fill(getDeltas(), 0);
|
Arrays.fill(getDeltas(), 0);
|
||||||
solve(a);
|
solve(a);
|
||||||
shareOutDelta();
|
int deltaMax = parentMin.value * getChildCount() + 1; //exclusive
|
||||||
arcsValid = false;
|
if (deltaMax < 2) {
|
||||||
forwardLinksValid = false;
|
return; //don't have any delta to distribute
|
||||||
backwardLinksValid = false;
|
}
|
||||||
groupBoundsValid = false;
|
int deltaMin = 0; //inclusive
|
||||||
|
|
||||||
|
float totalWeight = calculateTotalWeight();
|
||||||
|
|
||||||
|
int validDelta = -1; //delta for which a solution exists
|
||||||
|
boolean validSolution = true;
|
||||||
|
// do a binary search to find the max delta that won't conflict with constraints
|
||||||
|
while(deltaMin < deltaMax) {
|
||||||
|
final int delta = (deltaMin + deltaMax) / 2;
|
||||||
|
invalidateValues();
|
||||||
|
shareOutDelta(delta, totalWeight);
|
||||||
|
validSolution = solve(getArcs(), a, false);
|
||||||
|
if (validSolution) {
|
||||||
|
validDelta = delta;
|
||||||
|
deltaMin = delta + 1;
|
||||||
|
} else {
|
||||||
|
deltaMax = delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (validDelta > 0 && !validSolution) {
|
||||||
|
// last solution was not successful but we have a successful one. Use it.
|
||||||
|
invalidateValues();
|
||||||
|
shareOutDelta(validDelta, totalWeight);
|
||||||
solve(a);
|
solve(a);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private float calculateTotalWeight() {
|
||||||
|
float totalWeight = 0f;
|
||||||
|
for (int i = 0, N = getChildCount(); i < N; i++) {
|
||||||
|
View c = getChildAt(i);
|
||||||
|
LayoutParams lp = getLayoutParams(c);
|
||||||
|
Spec spec = horizontal ? lp.columnSpec : lp.rowSpec;
|
||||||
|
totalWeight += spec.weight;
|
||||||
|
}
|
||||||
|
return totalWeight;
|
||||||
|
}
|
||||||
|
|
||||||
private void computeLocations(int[] a) {
|
private void computeLocations(int[] a) {
|
||||||
if (!hasWeights()) {
|
if (!hasWeights()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user