2013-05-31 26 views
3

我見過很多關於如何實現與網格的其餘部分一起滾動的GridView標題的解決方案。android gridview頭解決方案與適配器回收單元格

其中大部分是創建一個listviewout或相關的佈局,其中包含一個標題視圖和一個gridview所有內部滾動視圖。這個解決方案有一個問題,即scrollview不知道網格的大小,所以爲了克服,你需要像這樣擴展網格視圖:https://stackoverflow.com/a/4536955/751180

但問題是,但這樣做,你迫使gridview呈現所有的物品一次不回收細胞。如果視圖包含圖像,這可能會導致應用程序崩潰,尤其是內存使用率過高。

其他人正在使用Listviews並根據屏幕大小計算可以放置多少個列。我個人想繼續使用網格視圖。

有沒有人使用不同的方法實現了一個gridview標題?

回答

3

您可以嘗試使用以下庫https://github.com/maurycyw/HeaderGridView 可能有幫助。

+0

謝謝!你有沒有用過它? –

+0

是的。我已經嘗試過了,但對我而言沒有幫助。我切換到另一個解決方案 – gabin

+0

我也試過了,沒有幫助。它只是通過翻譯GridView畫布並在頂部繪製標題來完成一個混合。然而,頭是粘性的,它不會與GridView一起滾動,它不會接收和點擊事件。 –

4

我花了很多時間嘗試爲GridView設置正確的標題。沒有成功。看來,實現自定義GridView(從ListView繼承)是唯一合理的方法。下面是這種帶有頁眉和頁腳的GridView的示例:https://github.com/SergeyBurish/HFGridView

+0

適配器沒有在AsyncTask的onPostExecute()中設置。 – Dinesh

0

我自定義了網格視圖,頭像是來自sdcard位置源的圖像。我的整個項目放在下面。如果這對任何人都有幫助,請投我們來增加聲譽。

public class MainActivity extends Activity { 
    private File file; 

    LinearLayout linear; 
    ArrayList<Bitmap> listbitmap; 
    String[] folderlist ; 
    ExpandableHeightGridView gridview; 
    LinearLayout linearhere; 
    String imageInSD = Environment.getExternalStorageDirectory().getAbsolutePath() +"/Hi"; 

    ArrayList<String> mylist = new ArrayList<String>(); 


    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     linear = (LinearLayout) findViewById(R.id.linear); 
     File imagesSource = new File(imageInSD); 
     File[] dictoryFiles = imagesSource.listFiles(); 

     for(int i =0; i<dictoryFiles.length;i++){ 
      mylist.add(dictoryFiles[i].getName()); 
     } 

     folderlist = mylist.toArray(new String[mylist.size()]); 

     linearhere = new LinearLayout(getApplicationContext()); 
     linearhere.setOrientation(LinearLayout.VERTICAL); 
     for (int k = 0; k < folderlist.length; k++) { 



      TextView textview = new TextView(getApplicationContext()); 
      textview.setTextColor(Color.BLACK); 
      textview.setTextSize(20); 
      textview.setText(folderlist[k]); 

      gridview = new ExpandableHeightGridView(getApplicationContext()); 
      gridview.setId(Calendar.SECOND); 

      gridview.setLayoutParams(new GridView.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); 
      gridview.setBackgroundColor(Color.WHITE); 
      gridview.setNumColumns(3); 
      gridview.setColumnWidth(GridView.AUTO_FIT); 
      gridview.setVerticalSpacing(5); 
      gridview.setHorizontalSpacing(5); 
      gridview.setStretchMode(GridView.STRETCH_COLUMN_WIDTH); 


      listbitmap = new ArrayList<Bitmap>(); 
      file = new File(imageInSD + "/" + folderlist[k]); 
      File list[] = file.listFiles(); 

      for (int i = 0; i < list.length; i++) { 

       String sp=list[i].getName(); 
       //if(sp.startsWith("123")){ 
        //textview.setText(folderlist[k]); 
       File image = new File(imageInSD + "/"+folderlist[k]+"/" + list[i].getName()); 

       InputStream fis = null; 
       try { 
        fis = new FileInputStream(image.getAbsolutePath()); 
       } catch (FileNotFoundException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 

       BitmapFactory.Options options = new BitmapFactory.Options(); 
       options.inSampleSize = 2; 
       Bitmap bm = BitmapFactory.decodeStream(fis, null, options); 
       listbitmap.add(bm); 
       //} 
      } 
      gridview.setAdapter(new CustomGridAdapter(getApplicationContext(), 
        listbitmap)); 
      gridview.setExpanded(true); 

      linearhere.addView(textview); 
      linearhere.addView(gridview); 

     } 

     linear.addView(linearhere); 

    } 

} 

====================== 
class2 
====================== 

public class ExpandableHeightGridView extends GridView 
{ 

    boolean expanded = false; 

    public ExpandableHeightGridView(Context context) 
    { 
     super(context); 
    } 

    public ExpandableHeightGridView(Context context, AttributeSet attrs) 
    { 
     super(context, attrs); 
    } 

    public ExpandableHeightGridView(Context context, AttributeSet attrs, 
      int defStyle) 
    { 
     super(context, attrs, defStyle); 
    } 

    public boolean isExpanded() 
    { 
     return expanded; 
    } 

    @Override 
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
    { 
     // HACK! TAKE THAT ANDROID! 
     if (isExpanded()) 
     { 
      // Calculate entire height by providing a very large height hint. 
      // View.MEASURED_SIZE_MASK represents the largest height possible. 
      int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK, 
        MeasureSpec.AT_MOST); 
      super.onMeasure(widthMeasureSpec, expandSpec); 

      ViewGroup.LayoutParams params = getLayoutParams(); 
      params.height = getMeasuredHeight(); 
     } 
     else 
     { 
      super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
     } 
    } 

    public void setExpanded(boolean expanded) 
    { 
     this.expanded = expanded; 
    } 
} 

====================== 
class 3: 
====================== 
public class CustomGridAdapter extends BaseAdapter { 

    private Context context; 
    private final ArrayList<Bitmap> gridValues; 

    // Constructor to initialize values 
    public CustomGridAdapter(Context context, ArrayList<Bitmap> gridValues) { 

     this.context = context; 
     this.gridValues = gridValues; 
    } 

    @Override 
    public int getCount() { 

     // Number of times getView method call depends upon gridValues.length 
     return gridValues.size(); 
    } 

    @Override 
    public Object getItem(int position) { 

     return position; 
    } 

    @Override 
    public long getItemId(int id) { 

     return id; 
    } 

    // Number of times getView method call depends upon gridValues.length 

    public View getView(int position, View convertView, ViewGroup parent) { 

     // LayoutInflator to call external grid_item.xml file 

     LayoutInflater inflater = (LayoutInflater) context 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

     View gridView; 

     if (convertView == null) { 

      gridView = new View(context); 

      // get layout from grid_item.xml (Defined Below) 

      gridView = inflater.inflate(R.layout.grid_item, null); 

      ImageView imageView = (ImageView) gridView 
        .findViewById(R.id.grid_item_image); 

      imageView.setImageBitmap(gridValues.get(position)); 

     } else { 

      gridView = (View) convertView; 
     } 

     return gridView; 
    } 
} 
========================= 
activity_main.xml Code: 
========================= 

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 

    android:layout_height="wrap_content" > 

      <LinearLayout 
       android:id="@+id/linear" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:background="#D8D8D8" 

       android:orientation="vertical" > 

      </LinearLayout> 


</ScrollView> 

========================== 
grid_item.xml code: 
========================== 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:padding="5dp" > 

    <ImageView 
     android:id="@+id/grid_item_image" 
     android:layout_width="180dp" 
     android:layout_margin="5dp" 
     android:layout_height="150dp" 
     > 
    </ImageView> 

    <LinearLayout 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:orientation="vertical" 
     android:padding="0dp" > 

    </LinearLayout> 

</LinearLayout> 
+0

嗨,我實現了這樣的要求,我張貼整個代碼堆棧上流。你可以從下面的鏈接找到代碼。 http://stackoverflow.com/questions/16860872/android-gridview-header-solution-with-adapter-recycling-cells/28893899#28893899 –

0

我有點晚了回答,但以我的經驗,這是有可能通過使用GridLayoutManager.SpanSizeLookup輔助類的RecyclerView API。例如,您可以在活動/片段中執行以下操作。

mRecyclerView = (RecyclerView) view.findViewById(R.id.your_recycler_view); 
mLayoutManager = new GridLayoutManager(mContext, 2); 
mLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { 
    @Override 
    public int getSpanSize(int position) { 
     if (position == 0) { 
      return 2; 
     } else { 
      return 1; 
     } 
    } 
}); 
mRecyclerView.setLayoutManager(mLayoutManager); 
mAdapter = new RecyclerAdapter(); 
mRecyclerView.setAdapter(mAdapter); 

如果您在網格(位置== 0)的開始,你的ViewHolder將得到最大列跨度,這是2在這種情況下。在您的適配器類中,您將需要爲視圖類型的標題和項目指定常量,並覆蓋int getItemViewType(int position)方法以根據適配器位置返回視圖類型。然後在RecyclerView.ViewHolder onCreateViewHolder(ViewGroup container, int viewType)根據當前視圖類型膨脹適當的佈局。

希望這有助於未來的讀者。令人驚訝的是,我還沒有看到這個解決方案在GridView頭上的類似問題。