2013-12-20 25 views

回答

42

這個問題已經存在一些解決方案。你正在描述的是節標題,並且在Android中被稱爲粘性版塊標題。

+4

嘗試我在這裏得到的選項後,HeaderListView似乎是最適合我的需求,並且比其他人更兼容。謝謝 –

+0

我現在無法訪問github.io上的HeaderListView。這裏是直接鏈接到github.com:https://github.com/applidium/HeaderListView – Andy

+0

哪些支持快速滾動? –

1

在app.gradle文件中添加此

compile 'se.emilsjolander:StickyScrollViewItems:1.1.0' 

然後我的佈局,在那裏我已經添加android:tag ="sticky"像TextView的具體意見或edittext不是LinearLayout,看起來像這樣。它也使用數據綁定,忽略這一點。爲TextView的

<?xml version="1.0" encoding="utf-8"?> 
<layout xmlns:android="http://schemas.android.com/apk/res/android"> 

    <data> 

     <variable 
      name="temp" 
      type="com.lendingkart.prakhar.lendingkartdemo.databindingmodel.BusinessDetailFragmentModel" /> 

     <variable 
      name="presenter" 
      type="com.lendingkart.prakhar.lendingkartdemo.presenters.BusinessDetailsPresenter" /> 
    </data> 

    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:orientation="vertical"> 


     <com.lendingkart.prakhar.lendingkartdemo.customview.StickyScrollView 
      android:id="@+id/sticky_scroll" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent"> 
      <!-- scroll view child goes here --> 
      <LinearLayout 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:orientation="vertical"> 


       <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:layout_gravity="center" 
        card_view:cardCornerRadius="5dp" 
        card_view:cardUseCompatPadding="true"> 

        <LinearLayout 
         android:layout_width="match_parent" 
         android:layout_height="match_parent" 
         android:orientation="vertical"> 


         <TextView 
          style="@style/group_view_text" 
          android:layout_width="match_parent" 
          android:layout_height="wrap_content" 
          android:background="@drawable/businessdetailtitletextviewbackground" 
          android:padding="@dimen/activity_horizontal_margin" 
          android:tag="sticky" 
          android:text="@string/business_contact_detail" /> 

         <android.support.design.widget.TextInputLayout 
          android:layout_width="match_parent" 
          android:layout_height="wrap_content" 
          android:layout_margin="7dp"> 

          <android.support.design.widget.TextInputEditText 
           android:layout_width="match_parent" 
           android:layout_height="wrap_content" 
           android:hint="@string/comapnyLabel" 
           android:textSize="16sp" /> 

         </android.support.design.widget.TextInputLayout> 

         <android.support.design.widget.TextInputLayout 
          android:layout_width="match_parent" 
          android:layout_height="wrap_content" 
          android:layout_margin="5dp"> 

          <android.support.design.widget.TextInputEditText 
           android:layout_width="match_parent" 
           android:layout_height="wrap_content" 
           android:hint="@string/contactLabel" 
           android:textSize="16sp" /> 

         </android.support.design.widget.TextInputLayout> 

         <android.support.design.widget.TextInputLayout 
          android:layout_width="match_parent" 
          android:layout_height="wrap_content" 
          android:layout_margin="5dp"> 

          <android.support.design.widget.TextInputEditText 
           android:layout_width="match_parent" 
           android:layout_height="wrap_content" 
           android:hint="@string/emailLabel" 
           android:textSize="16sp" /> 

         </android.support.design.widget.TextInputLayout> 

         <android.support.design.widget.TextInputLayout 
          android:layout_width="match_parent" 
          android:layout_height="wrap_content" 
          android:layout_margin="5dp"> 

          <android.support.design.widget.TextInputEditText 
           android:layout_width="match_parent" 
           android:layout_height="wrap_content" 
           android:hint="@string/NumberOfEmployee" 
           android:textSize="16sp" /> 

         </android.support.design.widget.TextInputLayout> 


        </LinearLayout> 
       </android.support.v7.widget.CardView> 

       <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:layout_gravity="center" 
        card_view:cardCornerRadius="5dp" 
        card_view:cardUseCompatPadding="true"> 

        <TextView 
         style="@style/group_view_text" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:background="@drawable/businessdetailtitletextviewbackground" 
         android:padding="@dimen/activity_horizontal_margin" 
         android:tag="sticky" 
         android:text="@string/nature_of_business" /> 


       </android.support.v7.widget.CardView> 

       <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:layout_gravity="center" 
        card_view:cardCornerRadius="5dp" 
        card_view:cardUseCompatPadding="true"> 

        <TextView 
         style="@style/group_view_text" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:background="@drawable/businessdetailtitletextviewbackground" 
         android:padding="@dimen/activity_horizontal_margin" 
         android:tag="sticky" 
         android:text="@string/taxation" /> 


       </android.support.v7.widget.CardView> 



      </LinearLayout> 
     </com.lendingkart.prakhar.lendingkartdemo.customview.StickyScrollView> 


    </LinearLayout> 
</layout> 

風團看起來這

<style name="group_view_text" parent="@android:style/TextAppearance.Medium"> 
     <item name="android:layout_width">wrap_content</item> 
     <item name="android:layout_height">wrap_content</item> 
     <item name="android:textColor">@color/edit_text_color</item> 
     <item name="android:textSize">16dp</item> 
     <item name="android:layout_centerVertical">true</item> 
     <item name="android:textStyle">bold</item> 
    </style> 

和TextView的背景是這樣的:(@繪製/ businessdetailtitletextviewbackground)

<?xml version="1.0" encoding="utf-8"?> 
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item> 
     <shape android:shape="rectangle"> 
      <solid android:color="@color/edit_text_color" /> 
     </shape> 
    </item> 
    <item android:bottom="2dp"> 
     <shape android:shape="rectangle"> 
      <solid android:color="@color/White" /> 
     </shape> 
    </item> 
</layer-list> 
5

編輯:有一些空閒時間添加完整工作示例的代碼。據此編輯答案。

對於那些不想使用第三方代碼(或不能直接使用它,例如在Xamarin中)的用戶,這可以通過手工很容易地完成。 這個想法是使用另一個ListView作爲標題。此列表視圖僅包含標題項目。它不會被用戶滾動(setEnabled(false)),但會根據主列表的滾動從代碼中滾動。所以你將有兩個列表 - headerListview和mainListview,以及兩個相應的適配器headerAdapter和mainAdapter。 headerAdapter僅返回節視圖,而mainAdapter支持兩種視圖類型(節和項)。您將需要一個方法,它在主列表中佔據一個位置,並在部分列表中返回相應的位置。

主要活動

public class MainActivity extends AppCompatActivity { 

    public static final int TYPE_SECTION = 0; 
    public static final int TYPE_ITEM = 1; 

    ListView mainListView; 
    ListView headerListView; 
    MainAdapter mainAdapter; 
    HeaderAdapter headerAdapter; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     mainListView = (ListView)findViewById(R.id.list); 
     headerListView = (ListView)findViewById(R.id.header); 
     mainAdapter = new MainAdapter(); 
     headerAdapter = new HeaderAdapter(); 

     headerListView.setEnabled(false); 
     headerListView.setAdapter(headerAdapter); 
     mainListView.setAdapter(mainAdapter); 

     mainListView.setOnScrollListener(new AbsListView.OnScrollListener(){ 

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

      } 

      @Override 
      public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 
       // this should return an index in the headers list, based one the index in the main list. The logic for this is highly dependent on your data. 
       int pos = mainAdapter.getSectionIndexForPosition(firstVisibleItem); 
       // this makes sure our headerListview shows the proper section (the one on the top of the mainListview) 
       headerListView.setSelection(pos); 

       // this makes sure that headerListview is scrolled exactly the same amount as the mainListview 
       if(mainAdapter.getItemViewType(firstVisibleItem + 1) == TYPE_SECTION){ 
        headerListView.setSelectionFromTop(pos, mainListView.getChildAt(0).getTop()); 
       } 
      } 
     }); 
    } 

    public class MainAdapter extends BaseAdapter{ 
     int count = 30; 

     @Override 
     public int getItemViewType(int position){ 
      if((float)position/10 == (int)((float)position/10)){ 
       return TYPE_SECTION; 
      }else{ 
       return TYPE_ITEM; 
      } 
     } 

     @Override 
     public int getViewTypeCount(){ return 2; } 

     @Override 
     public int getCount() { return count - 1; } 

     @Override 
     public Object getItem(int position) { return null; } 

     @Override 
     public long getItemId(int position) { return position; } 

     public int getSectionIndexForPosition(int position){ return position/10; } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
      View v = getLayoutInflater().inflate(R.layout.item, parent, false); 
      position++; 
      if(getItemViewType(position) == TYPE_SECTION){ 
       ((TextView)v.findViewById(R.id.text)).setText("SECTION "+position); 

      }else{ 
       ((TextView)v.findViewById(R.id.text)).setText("Item "+position); 
      } 
      return v; 
     } 
    } 

    public class HeaderAdapter extends BaseAdapter{ 
     int count = 5; 

     @Override 
     public int getCount() { return count; } 

     @Override 
     public Object getItem(int position) { return null; } 

     @Override 
     public long getItemId(int position) { return position; } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
      View v = getLayoutInflater().inflate(R.layout.item, parent, false); 
      ((TextView)v.findViewById(R.id.text)).setText("SECTION "+position*10); 
      return v; 
     } 
    } 

} 

一對夫婦的事情,這裏要注意。我們不想在主視圖列表中顯示第一部分,因爲它會產生重複(它已經顯示在標題中)。爲了避免這種情況,在您的mainAdapter.getCount():

return actualCount - 1; 

,並確保第一行中的getView()方法是

position++; 

這樣,你的主目錄將是渲染所有細胞,但第一個。

另一件事是你要確保你的headerListview的高度匹配列表項的高度。在這個例子中,高度是固定的,但如果你的物品高度沒有設置爲dp中的精確值,那麼可能會非常棘手。請參考這個答案如何解決這個問題:https://stackoverflow.com/a/41577017/291688

主要佈局

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/activity_main" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin"> 
    <ListView 
     android:id="@+id/header" 
     android:layout_width="match_parent" 
     android:layout_height="48dp"/> 

    <ListView 
     android:id="@+id/list" 
     android:layout_below="@+id/header" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"/> 
</RelativeLayout> 

項目/頭佈局

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" android:layout_width="match_parent" 
    android:layout_height="48dp"> 
    <TextView 
     android:id="@+id/text" 
     android:gravity="center_vertical" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     /> 

</LinearLayout> 
+0

可以提供一個完整的工作示例嗎?謝謝! – David

+0

添加示例 –

+0

謝謝你回答 – David