web-dev-qa-db-ja.com

ListViewのサイズが変更されたときに、ListViewの最後の表示アイテムを保持する

私が欲しいのはシンプルです、少なくとも私はシンプルだと思いました。 EditTextが画面の下部にあり、残りのスペースがListViewで埋められているウィンドウが欲しいだけです。残念ながら、期待通りに動作しませんでした。私が欲しいのは次の画像です。 XMLでこれを行う簡単な方法はありますか、またはこのための特別なコードを記述する必要がありますか? What I want

私の問題Androidソースコード。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout  xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="fill_parent"
Android:orientation="vertical" >
<ListView
    Android:id="@+id/demolist"
    Android:layout_width="match_parent"
    Android:layout_height="fill_parent"
    Android:layout_weight="1"
     >
</ListView>
    <EditText
        Android:id="@+id/editText1"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content" 
        Android:layout_weight="0">
    </EditText>
</LinearLayout >
32
Damn Vegetables

あなたが欲しいもの

キーボードなしで最後に表示されるアイテム

Last Visible Item Without Keyboard

キーボードで最後に表示されるアイテム

Last Visible Item With Keyboard

入力が大きい最後の表示アイテム

Last Visible Item With larger input

これが私がやった方法です

概要

  • リストビューでAndroid:stackFromBottom = "true"およびAndroid:transcriptMode = "alwaysScroll"を設定します
  • 設定Android:windowSoftInputMode = "adjustPan"アクティビティ
  • リストビューが常に最後の位置までスクロールするように、新しいチャットを追加するときにadapter.notifyDataSetChanged();を呼び出します。
  • EditTextでAndroid:inputType = "textMultiLine"Android:maxLines = "4"を設定して、テキストボックスを拡大する

細部

アクティビティ

<activity Android:name="MainActivity"
Android:screenOrientation="portrait"
Android:windowSoftInputMode="adjustPan"></activity>

チャットビュー

<RelativeLayout
    Android:id="@+id/chat_header"
    Android:layout_width="fill_parent"
    Android:layout_height="40dp"
    Android:padding="3dp" >

    <Button
        Android:id="@+id/btnBackChat"
        Android:layout_width="35dp"
        Android:layout_height="35dp"
        Android:layout_alignParentLeft="true"
        Android:background="@drawable/back_button" />

    <TextView
        Android:id="@+id/txt_name"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_alignBottom="@+id/btnBackChat"
        Android:layout_centerHorizontal="true"
        Android:textColor="@Android:color/white"
        Android:textSize="18sp" />

    <ImageView
        Android:id="@+id/imgViewProfileChat"
        Android:layout_width="35dp"
        Android:layout_height="35dp"
        Android:layout_alignParentRight="true"
        />
</RelativeLayout>

<ListView
    Android:id="@+id/listView1"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:layout_above="@+id/form"
    Android:layout_below="@+id/chat_header"
    Android:stackFromBottom="true"
    Android:transcriptMode="alwaysScroll"/>

<RelativeLayout
    Android:id="@+id/form"
    Android:layout_width="fill_parent"
    Android:layout_height="wrap_content"
    Android:layout_alignParentBottom="true"
    Android:layout_alignParentLeft="true"
    Android:orientation="vertical" >

    <ImageButton
        Android:id="@+id/btnAttach"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_alignParentLeft="true"
        Android:layout_alignParentTop="true"
        Android:contentDescription="@string/attach"
        Android:src="@drawable/attach_icon" />

    <EditText
        Android:id="@+id/txtChat"
        Android:layout_width="fill_parent"
        Android:layout_height="wrap_content"
        Android:layout_toLeftOf="@+id/btnSend"
        Android:layout_toRightOf="@+id/btnAttach"
        Android:inputType="textMultiLine"
        Android:maxLines="4" />

    <Button
        Android:id="@+id/btnSend"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_alignParentRight="true"
        Android:layout_alignParentTop="true"
        Android:text="@string/send" />
</RelativeLayout>
19
sooraj.e

キーボードを表示する前に AdapterView.getLastVisiblePosition() を使用することをお勧めします。

ここで2つのソリューション:

  • editTextクリック時
  • リストビューをリッスンするOnScrollListener(およびそのonScroll関数)のおかげ

次に AdapterView.setSelection を使用して、EditTextフォーカスの後にこのアイテム(またはインデックス-2またはインデックス-3)にジャンプします。

7
Gorcyn

以下のように、AndroidManifest.xmlでAndroid:windowSoftInputMode="adjustPan"を使用できます

 <activity Android:name="com.example.SimpleListView"
            Android:label="@string/app_name"
            Android:windowSoftInputMode="adjustPan" >

これにより、必要な出力が生成されます。公式 Androidドキュメント

オプションで、リストビューの最後まで自動的にスクロールする場合は、リストビューにトランスクリプトモード(チャット機能を使用している場合)を指定できます。 Android:transcriptMode="normal"もチェックして、適切かどうかを確認できます。

関連 SO回答 。公式 Androidドキュメント

<ListView
Android:id="@+id/comments"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:transcriptMode="alwaysScroll">

これは、ほとんどの問題を解決するはずですが、私がテストしていない最後の問題(画像内)を除いて、.

3
jaga

ListView#onSizeChanged(int w、int h、int oldw、int oldh)のメソッドを次のようにオーバーライドするだけです。

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    if (getChildCount() == 0) {
        return;
    }
    final int lastVisiblePosition = getLastVisiblePosition();
    int firstVisiblePosition = getFirstVisiblePosition();

    View last = getChildAt(lastVisiblePosition - firstVisiblePosition);
    int top = last.getTop();
    final int newTop = top + (h - oldh);
    Log.d(getClass().getSimpleName(), "onSizeChanged(" + w + ", " + h + ", " + oldw + ", " + oldh + ")");
    if (mFocusSelector == null) {
        mFocusSelector = new FocusSelector();
    }
    post(mFocusSelector.setup(lastVisiblePosition, newTop));
    super.onSizeChanged(w, h, oldw, oldh);
}

private class FocusSelector implements Runnable {
    private int mPosition;
    private int mPositionTop;

    public FocusSelector setup(int position, int top) {
        mPosition = position;
        mPositionTop = top;
        return this;
    }

    public void run() {
        setSelectionFromTop(mPosition, mPositionTop);
    }
}
3
Presley Zheng

実際には、マニフェストのActivity宣言に追加することで、必要なのと同じ動作を得ましたAndroid:windowSoftInputMode="adjustResize"およびListView宣言Android:transcriptMode="normal"。キーボードと向きの両方の変更。

2
mbarrben

私は、Androidのレイアウトエンジンを作成しました。これにより、キーボードの非表示および表示状態の変化(他の多くのコア機能の中で)をリッスンできます。このライブラリは http:// phil -brown.github.io/AbLE/

jarlibsディレクトリに追加するだけで(存在しない場合はこのフォルダーを作成します)、Activityから継承する代わりに、AbLEActivityから継承します。次に、メソッドonKeyboardShownおよびonKeyboardHiddenをオーバーライドします。これらのメソッドでは、必要に応じてコンテンツビューを上下にアニメーション化できます。

@Override
public void onKeyboardShown() {
    //animate up
}

@Override
public void onKeyboardHidden() {
    //animate down
}
1
Phil

この機能も必要です。ここに私の試みがありますが、それはうまくいきません-スクロールは少し不安定で(常に本来あるべき場所になるとは限りません)、画面を回転させるときのスクロール位置の保持に干渉します。

@Override
public void onResume() {
    super.onResume();
    getListView().addOnLayoutChangeListener(stickyLastItemHandler);
}

@Override
public void onPause() {
    super.onPause();
    getListView().removeOnLayoutChangeListener(stickyLastItemHandler);
}

View.OnLayoutChangeListener stickyLastItemHandler = new View.OnLayoutChangeListener() {
    @Override
    public void onLayoutChange(View v,
            int left, int top, int right, int bottom,
            int oldLeft, int oldTop, int oldRight, int oldBottom) {

        final int heightChange = (bottom - top) - (oldBottom - oldTop);
        if (heightChange != 0) {
            ((AbsListView)v).smoothScrollBy(-heightChange, 1000);
        }
    }
};
1
Martin Stone

あなたはxmlを通じてそれを行うことができます:

<ListView
    Android:stackFromBottom="true"
    Android:layout_height=0dp
    Android:layout_weight=1 />

下からスタックすると、デフォルトでListViewが下にスクロールされます。ListViewのウェイトを設定すると、親垂直LinearLayout内のすべての可能なスペースが埋められます。

1

リストのデータがいつ変更されたかがわかっているとしたら、リストの選択を最後の行に設定することにより、リストを手動で一番下までスクロールするように指示できます。このようなもの:

private void scrollMyListViewToBottom() {
    myListView.post(new Runnable() {
        @Override
        public void run() {
            // Select the last row so it will scroll into view...
            myListView.setSelection(myListAdapter.getCount() - 1) ;
        }
    });
}

または、これを試すこともできます。

ChatAdapter adapter = new ChatAdapter(this);

ListView lview = (ListView) findViewById(R.id.chatList);
lview .setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
lview .setAdapter(adapter);

adapter.registerDataSetObserver(new DataSetObserver() {
    @Override
    public void onChanged() {
        super.onChanged();
        lv.setSelection(adapter.getCount() - 1);    
    }
});
0
Nipun Gogia
Follow these steps
--------------------
1. Update your activity in AndroidManifest.xml file like below
<activity
            Android:name=".MyListActivity"
            Android:windowSoftInputMode="adjustResize" />

2. Set your list view with like below.
mListView.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
mListView.setStackFromBottom(true);

それがあなたの問題を解決することを願っています。

0
Suresh Pichuka