Make CandidateView backward compatible

Up to version 10 (Gingerbread) of the API, FrameLayout doesn't handle
margin properly.  This change inserts RelativeLayout to FrameLayout as
placer to set margin and place children views absolutely.

Change-Id: Iee785bc2da77677738caf456bcd2bbf57b89f007
main
Tadashi G. Takaoka 2011-06-21 00:11:17 +09:00
parent b947c73dcc
commit a7eed902f1
3 changed files with 70 additions and 35 deletions

View File

@ -0,0 +1,52 @@
/*
* Copyright (C) 2011 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 com.android.inputmethod.compat;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
public class FrameLayoutCompatUtils {
private static final boolean NEEDS_FRAME_LAYOUT_HACK = (
android.os.Build.VERSION.SDK_INT < 11 /* Honeycomb */);
public static ViewGroup getPlacer(ViewGroup container) {
if (NEEDS_FRAME_LAYOUT_HACK) {
// Insert RelativeLayout to be able to setMargin because pre-Honeycomb FrameLayout
// could not handle setMargin properly.
final ViewGroup placer = new RelativeLayout(container.getContext());
container.addView(placer);
return placer;
} else {
return container;
}
}
public static MarginLayoutParams newLayoutParam(ViewGroup placer, int width, int height) {
if (placer instanceof FrameLayout) {
return new FrameLayout.LayoutParams(width, height);
} else if (placer instanceof RelativeLayout) {
return new RelativeLayout.LayoutParams(width, height);
} else if (placer == null) {
throw new NullPointerException("placer is null");
} else {
throw new IllegalArgumentException("placer is neither FrameLayout nor RelativeLayout: "
+ placer.getClass().getName());
}
}
}

View File

@ -42,11 +42,10 @@ import android.view.View;
import android.view.ViewConfiguration; import android.view.ViewConfiguration;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams; import android.view.ViewGroup.MarginLayoutParams;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.PopupWindow; import android.widget.PopupWindow;
import android.widget.TextView; import android.widget.TextView;
import com.android.inputmethod.compat.FrameLayoutCompatUtils;
import com.android.inputmethod.keyboard.internal.Key; import com.android.inputmethod.keyboard.internal.Key;
import com.android.inputmethod.keyboard.internal.MiniKeyboardBuilder; import com.android.inputmethod.keyboard.internal.MiniKeyboardBuilder;
import com.android.inputmethod.keyboard.internal.PointerTrackerQueue; import com.android.inputmethod.keyboard.internal.PointerTrackerQueue;
@ -946,27 +945,12 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
} }
private void addKeyPreview(TextView keyPreview) { private void addKeyPreview(TextView keyPreview) {
ViewGroup placer = mPreviewPlacer; if (mPreviewPlacer == null) {
if (placer == null) { mPreviewPlacer = FrameLayoutCompatUtils.getPlacer(
final FrameLayout screenContent = (FrameLayout) getRootView().findViewById( (ViewGroup)getRootView().findViewById(android.R.id.content));
android.R.id.content);
if (android.os.Build.VERSION.SDK_INT >= /* HONEYCOMB */11) {
placer = screenContent;
} else {
// Insert LinearLayout to be able to setMargin because pre-Honeycomb FrameLayout
// could not handle setMargin properly.
placer = new LinearLayout(getContext());
screenContent.addView(placer);
}
mPreviewPlacer = placer;
}
if (placer instanceof FrameLayout) {
// Honeycomb or later.
placer.addView(keyPreview, new FrameLayout.LayoutParams(0, 0));
} else {
// Gingerbread or ealier.
placer.addView(keyPreview, new LinearLayout.LayoutParams(0, 0));
} }
final ViewGroup placer = mPreviewPlacer;
placer.addView(keyPreview, FrameLayoutCompatUtils.newLayoutParam(placer, 0, 0));
} }
// TODO: Introduce minimum duration for displaying key previews // TODO: Introduce minimum duration for displaying key previews

View File

@ -44,6 +44,7 @@ import android.widget.LinearLayout;
import android.widget.PopupWindow; import android.widget.PopupWindow;
import android.widget.TextView; import android.widget.TextView;
import com.android.inputmethod.compat.FrameLayoutCompatUtils;
import com.android.inputmethod.compat.LinearLayoutCompatUtils; import com.android.inputmethod.compat.LinearLayoutCompatUtils;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
@ -244,7 +245,8 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
public void setListener(Listener listener, View inputView) { public void setListener(Listener listener, View inputView) {
mListener = listener; mListener = listener;
mKeyboardView = inputView.findViewById(R.id.keyboard_view); mKeyboardView = inputView.findViewById(R.id.keyboard_view);
mCandidatesPane = (ViewGroup)inputView.findViewById(R.id.candidates_pane); mCandidatesPane = FrameLayoutCompatUtils.getPlacer(
(ViewGroup)inputView.findViewById(R.id.candidates_pane));
mCandidatesPane.setOnClickListener(this); mCandidatesPane.setOnClickListener(this);
mCandidatesPaneContainer = (ViewGroup)inputView.findViewById( mCandidatesPaneContainer = (ViewGroup)inputView.findViewById(
R.id.candidates_pane_container); R.id.candidates_pane_container);
@ -346,12 +348,10 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
} }
if (x != 0) { if (x != 0) {
final View divider = mDividers.get(i - NUM_CANDIDATES_IN_STRIP); final View divider = mDividers.get(i - NUM_CANDIDATES_IN_STRIP);
mCandidatesPane.addView(divider); addCandidateAt(divider, x, y);
placeCandidateAt(divider, x, y);
x += dividerWidth; x += dividerWidth;
} }
mCandidatesPane.addView(tv); addCandidateAt(tv, x, y);
placeCandidateAt(tv, x, y);
x += width; x += width;
} }
@ -372,14 +372,13 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
} }
} }
private void placeCandidateAt(View v, int x, int y) { private void addCandidateAt(View v, int x, int y) {
ViewGroup.LayoutParams lp = v.getLayoutParams(); final int width = v.getMeasuredWidth();
if (lp instanceof ViewGroup.MarginLayoutParams) { final int height = v.getMeasuredHeight();
ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams)lp; final MarginLayoutParams marginLayoutParams = FrameLayoutCompatUtils.newLayoutParam(
mlp.width = v.getMeasuredWidth(); mCandidatesPane, width, height);
mlp.height = v.getMeasuredHeight(); marginLayoutParams.setMargins(x, y + (mCandidateStripHeight - height) / 2, 0, 0);
mlp.setMargins(x, y + (mCandidateStripHeight - mlp.height) / 2, 0, 0); mCandidatesPane.addView(v, marginLayoutParams);
}
} }
private void centeringCandidates(int from, int to, int width, int paneWidth) { private void centeringCandidates(int from, int to, int width, int paneWidth) {