ListView
などの要素のサイズを適切に変更できません。
ダッシュボード、エディットボックス、リストビューを備えた検索用のListActivity
を入手しました。アイデアは、キーボードが表示されている間、アクションバーを非表示にすることです。
ビューサイズの変更をリッスンするためにLinearLayout
を拡張しました(推奨されるように ここ ):
public class SizeChangingLinearLayout extends LinearLayout {
//...
@Override
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld)
{
View actionbar = mainView.findViewById(R.id.actionbar);
if (yNew > yOld)
actionbar.setVisibility(View.VISIBLE);
else if (yNew < yOld)
actionbar.setVisibility(View.GONE);
super.onSizeChanged(xNew, yNew, xOld, yOld);
}
}
アクションバーの非表示/表示は期待どおりに機能しますが、非表示のアクションバーと同じ高さのListView
の下にギャップがあります。グラフィックが変更されるとすぐに(たとえば、編集ボックスに書き込む)、ListView
がギャップを埋めます。キーボードを非表示にすると、同様の動作が逆に表示されます。
[編集]
他のレイアウトを変更する場合にも同じ問題が発生します。 Visibility
内のonSizeChanged
を変更すると直接表示されますが、サイズとマージンを変更しても、他のユーザーアクションでそれらのビューが再描画されるまで表示されません。 onSizeChanged
からの無効化は機能しません。
[/編集]
私は次の方法でグラフィックを更新しようとしました:
invalidate
-カスタムLinearLayoutとListView
の両方を使用する(推奨されるように ここ )notifyDataSetChanged
forceLayout
...そしてもっと、成功せずに。 ListView
が最初にサイズ変更されないのはなぜですか?拡張LinearLayoutでonLayout
をオーバーライドする必要がありますか?私は何を逃しましたか?
onSizeChanged()
の最後に以下を追加すると、問題が解決します。
Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
requestLayout();
}
});
この質問への回答を参照してください: サイズ変更後にレンダリングされないカスタムViewGroup内のビュー
高さを1px変更して呼び出すことにより、ListViewを強制的に再描画できます。
requestLayout()
これはロングショットかもしれません...
ListView
のAndroid:layout_height=""
設定で遊んでみましたか?
match_parent
またはwrap_content
を使用すると、強制的に動作する可能性があります。
私が言ったように...ロングショット!
setOnFocusChangeListener
とsetOnClickListener
をEditText
に登録することで、やりたいことができます。
ナビゲーションに関しては、考慮すべきさまざまなシナリオがたくさんあり、特定のレイアウトで機能するように変更する必要がある場合があります。
とにかく、戻るボタンがタッチされたときに非表示の要素を表示するには、onSizeChangedをオーバーライドすることから始めます。
public class MyLinearLayout extends LinearLayout {
private MyListActivity mMyListActivity;
public MyLinearLayout(Context context) {
super(context);
}
public MyLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setMyListActivity(MyListActivity mla) {
mMyListActivity = mla;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// show the element when we get more room
if (h > oldh) {
if (mMyListActivity != null) {
mMyListActivity.showBar();
}
}
super.onSizeChanged(w, h, oldw, oldh);
}
}
ListActivityで、MyLinearLayoutを取得し、それにthis
を渡します。次に、SetOnFocusChangeListenerが登録され、EditTextのフォーカスが変更されたときに処理します。 setOnClickListenerは、EditTextにすでにフォーカスがある場合に要素を非表示にするために使用されます。
public class MyListActivity extends ListActivity {
private ArrayList<MyData> mDataList = new ArrayList<MyData>();
private MyLinearLayout mMyLinearLayout;
private LinearLayout mHideMeLinearLayout;
private EditText mEditText;
public void showBar() {
if (mHideMeLinearLayout != null) {
mHideMeLinearLayout.setVisibility(View.VISIBLE);
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Get MyLinearLayout and pass this to it.
mMyLinearLayout = (MyLinearLayout) findViewById(R.id.myLinearLayout);
mMyLinearLayout.setMyListActivity(this);
// the LinearLayout to be hidden
mHideMeLinearLayout = (LinearLayout) findViewById(R.id.LinearLayoutToHide);
mEditText = (EditText) findViewById(R.id.editText);
mEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
InputMethodManager imm = (InputMethodManager) getSystemService(Service.INPUT_METHOD_SERVICE);
if (hasFocus) {
imm.showSoftInput(mEditText, 0);
mHideMeLinearLayout.setVisibility(View.GONE);
} else {
imm.hideSoftInputFromWindow(mMyLinearLayout.getWindowToken(), 0);
mHideMeLinearLayout.setVisibility(View.VISIBLE);
}
}
});
mEditText.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mHideMeLinearLayout.setVisibility(View.GONE);
}
});
.....
}
.....
}
後で実用的な例を示しますが、今すぐ実行する必要があります。