2016-04-15 30 views
0

水平線LinearLayout(画面幅に一致)では、2つのListViewインスタンス(動的リスト項目を含む)とその間にTextViewがあります。 TextViewをキャンバスとして使用して、左のリストビュー内の選択したリストアイテムを、右のリストビュー内のすべてのリストアイテムと、またはその逆に接続する(ベジェ)線を描画したいと思います。選択されたリストアイテムまたは他の側のリストアイテムのいずれかがListViewの可視領域外にあることが完全に可能になりました。この場合、私はそれらの線を上に/下から、上から/下にとどめて、それらが見える限り描きたいと思います。これらの線を描くためには、各行の最初と最後にxとyの値が必要です。 xはtextView.getLeft()とtextView.getRight()ですが、yは2つのリストの現在のスクロール位置に依存します。ListView項目のY()の取得方法

私の問題は、特定のListView項目の現在のyの値を取得することです:

list.getChildAt(indexOfCurrentlySelectedItem).getY() 

私はリストがレイアウトされた後、それらの値にアクセスする必要があります。どのリスト項目が表示されていないか、どのリスト項目が表示されていないかを判断する必要があります(表示されないリスト項目にはy値がありますか?ビュー?リサイクル可能なビュー(ホルダーパターンを使用しています)?これらのy値をTextViewのonDrawメソッドに渡すために、リストを反復処理する必要があります。最後に、スクロールが発生した後に行を再描画するメカニズムをインストールする必要があります。

(レイアウト後とスクロール後に)現在のy値を保持する方法を教えてください。 OnScrollListenerの表示位置を追跡する必要がありますか? OnGlobalLayoutListenerでリストレイアウトの終わりをリッスンする必要がありますか?私は(また)すべてのリストアイテムのOnGlobalLayoutListenerでリストアイテムレイアウトの終わりをリッスンする必要がありますか?

答えて

0

私は良い解決策を見つけました.OnScrollListenerは必要なものすべてを提供しますが、ここではOnGlobalLayoutListenerは必要ありません。

public class ArrayListAdapter extends ArrayAdapter<String> 
    implements AbsListView.OnScrollListener 

... 

@Override 
public void onScrollStateChanged(AbsListView view, int scrollState) {} 

@Override 
public synchronized void onScroll(final AbsListView listView, int firstVisibleItem, 
            int visibleItemCount, int totalItemCount) { 
    List<Integer>yList = new ArrayList<>(); 
    int checkedPosition = listView.getCheckedItemPosition(); 
    double yChecked = 0; 

    for (int pos = 0; pos < totalItemCount; pos++) { 
     CheckedTextView tv = (CheckedTextView) this 
       .getViewByPosition(pos, listView, firstVisibleItem, 
         firstVisibleItem + visibleItemCount - 1); 
     if (pos == checkedPosition) { 
      yChecked = tv.getY(); 
     } 
     yList.add(pos, tv.getY()); 
    }   
    // Here I pass the fresh y-values to the fragment holding the 
    // two ListViews. After some further calculations the fragment 
    // passes the data to the TextView where it is stored and 
    // this.invalidate is called to eventually trigger the onDraw method. 
    originalFragment.setScrollData(yList, yChecked); 
} 

private View getViewByPosition(int pos, AbsListView listView, int firstVisibleItem, 
           int lastVisibleItem) { 
    if (pos < firstVisibleItem || pos > lastVisibleItem) { 
     // The next line is the only downside of this solution I have 
     // found so far. If the convertView of the getView(int 
     // position, View convertView, ViewGroup parent) method is null 
     // the holder pattern I applied in my adapter becomes useless. 
     // In my case the recreation of the CheckedTextViews is fast 
     // enough though. 
     return listView.getAdapter().getView(pos, null, listView); 
    } else { 
     return listView.getChildAt(pos - firstVisibleItem); 
    } 
} 
関連する問題