ListViewにおけるitem footerview headerviewのレイアウトイベント傍受などの問題の収集整理

11508 ワード

イベントの問題:
---------------------------------------------------------
1、item内にbuttonなどのコントロールがある場合、listviewのonitemclickイベントを傍受すると、item内のbutton、imagebuttonなどのコントロールに焦点が奪われ、
これによりlistviewでonitemclickイベントが設定された後にトリガーされません.解決策はitemを初期化する際に内部buttonなどのコントロールの焦点取得を遮断することであり、
特定のメソッドは、カスタムitemのルートコントロールで呼び出すことができます.
 
      [java]  view plain copy
      setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);   
これによりサブコントロールの焦点を絞り込むことができ、listviewのonitemclickは正しくトリガーされ、item内部のbuttonなどのコントロールにも影響しません.
彼らはクリックされたときも自分のクリックイベントをトリガーすることができます.
2.listviewにheaderviewを追加する必要がある場合、listviewのaddHeaderView(headView,null,false)メソッドを呼び出すことで、
この方法には、addHeaderView(headView)のリロード方法もある.この2つの方法の違いは、ヘッダーがselectedされるかどうかを制御できることです.
selectedされたくない場合は、3番目のパラメータをfalseに設定します.
3.次に上記のヘッダを追加する、ヘッダを追加するときに呼び出されるaddHeaderViewメソッドはlistviewに置かなければならない.setadapterの前に、
リストビューにヘッダを追加するには、adapterをバインドする前に追加する必要があります.そうしないと、エラーが発生します.
setAdapterメソッドを呼び出すとandroidは現在のlistviewにheaderが追加されているかどうかを判断します.
追加した場合、私たちが設定したadapterのすべての内容とlistviewのheaderとfooterを含む新しいtempadapterが生成されます.
だからlistviewにheaderを追加した後、プログラムでlistviewを呼び出します.getadapterでは、setadapterを介して渡されたadapterではなくtempadapterが返されます.
adapterが設定されていない場合はtempadapterは私たち自身のadapterと同じです.listview.getadapter().getcount()メソッドの戻り値は予想より大きくなります.
ヘッダーが追加されたためです.
4、上のtempadapterによると、adapterのgetitemメソッドをカスタマイズして戻ってくるpositionにはheaderは含まれていません.
カスタムadapterのデータposition番号は0から始まります.つまり、私たちが送ったリストの位置と同じです.
 
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//TODO Auto-generated method stub
Log.i("adapter", "position:"+position);//このpositionは私たちのデータの本当の位置です
}
listviewのonitemclickメソッドでは、
public void onItemSelected(AdapterView parent, View view, int position, long id)
positionは現在のclickの位置であり、この位置はHeaderView ListAdapterの位置を指し、0からlistviewにheaderが追加された場合、0はheaderを表す.
[java]  view plain copy
  • @Override  
  • public View getView(int position, View convertView, ViewGroup parent) {  
  • // TODO Auto-generated method stub  
  • Log.i("adapter", "position:"+position);//このpositionは私たちのデータの本当の位置
  • です.
  •   }  

  • listviewのonitemclickメソッドでは、
     
    [java]  view plain copy
  • public void onItemClick(AdapterView

  • headViewとfooterViewはonItemClickメソッドに応答でき、headViewのpositionは0、footerViewのpositionは最大です.
    ただし、OnItemClickを上書きするには、headViewとfooterViewにOnClickListenerを設定します.
    これにより、headviewまたはfooterViewをクリックすると、onItemClick()ではなくOnClickListenerがトリガーされます.
    レイアウトの問題:
    ---------------------------------------------------------
    ListViewのプルアップで発生した問題は、どのような原理が分からないので、具体的にはよく研究されていません.Markはちょっと見てください.
    レイアウトインタフェースは次のとおりです.
    foot1.xml
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:gravity="center"  android:background="#f1f1f1" >
      
      <TextView   android:layout_width="wrap_content"   android:layout_height="50dip"   android:gravity="center"   android:text=" "   android:textSize="18sp" />
    
    </RelativeLayout>

    foot2.xml
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="match_parent"  android:layout_height="50dip"  android:gravity="center"  android:background="#f1f1f1" >
      
      <TextView   android:layout_width="wrap_content"   android:layout_height="wrap_content"   android:gravity="center"   android:text=" "   android:textSize="18sp" />
    
    </RelativeLayout>

    効果のように見える2つのレイアウトインタフェースは、ListViewのFooterViewでは2つの効果が表示されます.footer1.xmlにはTextViewの高さが50 dip、ルートレイアウトにはラップコンテンツが設定されているので、実際の表示効果ではListViewのFooterは確かに高さが50 dipとなり、
    でもfooter 2.xmlではルートレイアウトに高さ50 dipを設定していますが、実際にListViewのFooterViewにロードしても効果はありません.
    彼の高さはwrap_に変わりましたcontent、TextViewの高さもwrap_に設定contentなので、実際に表示される高さはTextViewコンテンツの高さ、つまりフォントの高さです.
    ********************************************************************
    ListViewのheaderとfooterを動的に表示、非表示にする必要がある場合は、以前は直接setVisibilityの中のViewをsetVisibilityと思っていた.GONEでいいです.
    しかし実際の使用ではそうではないことが分かった.GONEを直接設定すると、要素は非表示になりますが、
    でもやはりそのエリアを占拠しています.まるで...INVISIBILEのような効果になりました.その後、ネットで探してみたら発見されました.
    footerにlayoutか親のviewを追加すればいいです.
    例:(サンプルコード、header同様)
    ?
    1
    2
    3 private ListView listView = new ListView(context);
      private TextView footer = new TextView(context);
    そして直接
    ?
    1
    2
    3 listView.addFooterView(footer);
      footer.setVisibility(View.GONE);
    これじゃだめだ.必要
    ?
    1
    2
    3
    4
    5
    6
    7 LinearLayout footerParent = new LinearLayout(context);
      footerParent.addView(footer);
      listView.addFooterView(footerParent);
      footer.setVisibility(View.GONE);
    これで本当に欲しい効果が得られます.
    この効果を知る前に、removeとaddの方法を使って、比較的に憂鬱です.このような方式は迂回的な感じがし,booleanの変数を1つ増やして判断しなければならない.
    FooterViewの追加と削除について
    *3.1毎回、FooterViewを削除します.
    *3.2必要があればaddでFooterView
    私たちは通常、データをロードするときに、トラフィックを節約するために一度にデータをすべてダウンロードすることはありません.一般的には、セグメントダウンロードです.セグメントダウンロードでは、listviewの一番後ろに進捗バーが配置され、データがロードされていることを示します.データがロードされたら、またクリアします.この時は気をつけなければなりません.   mLoadingLayout = (FrameLayout) View.inflate(this, R.layout.load, null);    listView.addFooterView(mLoadingLayout);    listView.requestFocus();
    これはlistviewの末尾に進捗バーを追加します.listView.removeFooterView(mLoadingLayout); これは、末尾を除去する進捗バーです.削除時に空のポインタが返される場合がありますが、listviewはnullではなく、mLoadingLayoutもnullではありませんが、listviewが3つの部分に分かれているため、空のポインタが返されます.一つは頭部、二つは中間部、三つは尾部です.頭部または尾部が設けられている場合は、本当の意味で有効になるには中間部が必要です.有効でない場合は削除するとポインタエラーが表示されます.だからlistViewでremoveFooterView(mLoadingLayout);時
    リストビューを呼び出す必要があります.setAdapter(adapter);(中間部を設ける)
    adapterは、データは0でもnullでも構いません.