web-dev-qa-db-ja.com

onSizeChangedでサイズとレイアウトを設定するにはどうすればよいですか?

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がギャップを埋めます。キーボードを非表示にすると、同様の動作が逆に表示されます。

enter image description here

[編集]

他のレイアウトを変更する場合にも同じ問題が発生します。 Visibility内のonSizeChangedを変更すると直接表示されますが、サイズとマージンを変更しても、他のユーザーアクションでそれらのビューが再描画されるまで表示されません。 onSizeChangedからの無効化は機能しません。

[/編集]

私は次の方法でグラフィックを更新しようとしました:

  • invalidate-カスタムLinearLayoutとListViewの両方を使用する(推奨されるように ここ
  • リストのアダプタのnotifyDataSetChanged
  • forceLayout

...そしてもっと、成功せずに。 ListViewが最初にサイズ変更されないのはなぜですか?拡張LinearLayoutでonLayoutをオーバーライドする必要がありますか?私は何を逃しましたか?

27
JOG

onSizeChanged()の最後に以下を追加すると、問題が解決します。

Handler handler = new Handler();
handler.post(new Runnable() {

    @Override
    public void run() {
        requestLayout();
    }
});

この質問への回答を参照してください: サイズ変更後にレンダリングされないカスタムViewGroup内のビュー

36
aspartame

高さを1px変更して呼び出すことにより、ListViewを強制的に再描画できます。

requestLayout()

0
PravinCG

これはロングショットかもしれません...

ListViewAndroid:layout_height=""設定で遊んでみましたか?

match_parentまたはwrap_contentを使用すると、強制的に動作する可能性があります。

私が言ったように...ロングショット!

0
neildeadman

setOnFocusChangeListenersetOnClickListenerEditTextに登録することで、やりたいことができます。

ナビゲーションに関しては、考慮すべきさまざまなシナリオがたくさんあり、特定のレイアウトで機能するように変更する必要がある場合があります。

とにかく、戻るボタンがタッチされたときに非表示の要素を表示するには、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);
            }
        });

        .....
    }

    .....
}

後で実用的な例を示しますが、今すぐ実行する必要があります。

0
rochdev