4

これは私の初めての投稿であり、私は愚かな初心者なので、誰かが私を助け、私の無知を許してくれることを願っています.

ArrayAdapter が取り込まれた ListView があります。スクロールまたはクリックすると、選択したアイテム、または垂直方向の中央に最も近いアイテムが、画面の垂直方向の正確な中央に強制的に配置されます。listView.setSelection(int position) を呼び出すと、選択した位置が画面の上部に配置されるため、代わりに listView.setSelectionFromTop(position, offset) を使用する必要があります。オフセットを見つけるために、ListView の高さの半分からビューの高さの半分を取得します。

したがって、OnItemClick または OnScrollStateChanged 内で、次のようにすると、アイテムを垂直方向に簡単に中央揃えにすることができます。

        int x = listView.getHeight();
        int y = listView.getChildAt(0).getHeight();                 
        listView.setSelectionFromTop(myPosition, x/2 - y/2);

これはすべて正常に機能します。私の問題は、最初の ListView セットアップにあります。アクティビティの開始時にアイテムを中央に配置したいのですが、次から NullPointerException を取得するため、できません。

int y = listView.getChildAt(0).getHeight();

これは、ListView がまだレンダリングされていないためであり、OnCreate() または OnResume() からこれを呼び出したときに子がないためだと理解しています。

だから私の質問は簡単です:必要な高さの値を取得できるように、ListViewを起動時に強制的にレンダリングするにはどうすればよいですか? または、代わりに、ListView 内で項目を垂直方向に中央揃えする方法は他にありますか?

助けてくれてありがとう!

4

3 に答える 3

0

ここで自分の質問に答えていますが、それは非常にハックです。リストビューの動作に光を当てるので、興味深いと思います。

問題は、まだ存在していない (レンダリングされていない) データ (リストビュー行) を操作しようとしたことにありました。リストビューにはまだ子がないため、listview.getChildAt(int) は null でした。アクティビティが作成されるとすぐに onScroll() が呼び出されることがわかったので、単純にすべてをスレッドに入れ、getChildAt() 呼び出しを遅らせました。次に、すべてをブーリアンラッパーで囲み、(起動時に) 1 回だけ呼び出されるようにします。

興味深いことに、呼び出しを 1 ミリ秒遅らせるだけで、すべてが正常に機能するようになりました。そして、それは目で見るには速すぎます。

私が言ったように、これはすべてハックなので、これはすべて悪い考えだと確信しています. 助けてくれてありがとう!

private boolean listViewReady = false;

public void onScroll(AbsListView view, int firstVisibleItem,
        int visibleItemCount, int totalItemCount) {

    if (!listViewReady){
        Thread timer = new Thread() {
            public void run() {
                try{
                    sleep(1);
                }catch (InterruptedException e) {
                    e.printStackTrace();
                }finally{                   
                    runOnUiThread(new Runnable() {
                         public void run() {
                             myPosition = 2;
                             int x = listView.getHeight();
                             int y = listView.getChildAt(0).getHeight();                 
                             listView.setSelectionFromTop(myPosition, x/2 - y/2);
                             listViewReady = true;
                        }
                    });                     
                }
            }
        };
        timer.start();
    }//if !ListViewReady
于 2012-06-12T08:06:29.073 に答える
0

私は、私の意見では、わずかに単純なソリューションを使用して同じことを達成しました

mListView.post(new Runnable() {
   @Override
   public void run() {
      int height = mListView.getHeight();
      int itemHeight = mListView.getChildAt(0).getHeight();
      if (positionOfMyItem == myCollection.size() - 1) {
        // last element - > don't subtract item height
        itemHeight = 0;
    }
    mListView.setSelectionFromTop(position, height / 2 - itemHeight / 2);
   }
});
于 2013-02-13T14:09:14.257 に答える