類似 QQ 空間相冊列表:按時間/相冊分組,組頭懸浮固定,組內圖片網格滾動。
GitHub: TonicArtos/StickyGridHeaders
// build.gradle
implementation 'com.tonicartos:stickygridheaders:1.0.1'
public class Photo {
public String path;
public long dateTaken; // 用於分組
}
public class PhotoGroup {
public String headerTitle; // 如 "2024年1月"
public List photos;
}
public class PhotoAdapter extends BaseAdapter
implements StickyGridHeadersBaseAdapter {
private List groups;
@Override public int getCount() {
return groups.stream().mapToInt(g -> g.photos.size()).sum();
}
@Override public Object getItem(int position) { /* 扁平化索引轉換 */ }
@Override public long getItemId(int position) { return position; }
@Override public View getView(int position, View convertView, ViewGroup parent) {
// 普通 GridView 邏輯:加載圖片
}
// StickyGridHeaders 必須實現
@Override public int getCountForHeader(int header) {
return groups.get(header).photos.size();
}
@Override public int getNumHeaders() {
return groups.size();
}
@Override public View getHeaderView(int header, View convertView, ViewGroup parent) {
// 返回組頭 View (TextView 顯示 groups.get(header).headerTitle)
}
@Override public long getHeaderId(int header) {
return header; // 穩定 ID
}
}
<com.tonicartos.widget.stickygridheaders.StickyGridHeadersGridView
xmlns:android="https://schemas.android.com/apk/res/android"
android:id="@+id/grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="3"
android:verticalSpacing="4dp"
android:horizontalSpacing="4dp" />
StickyGridHeadersGridView grid = findViewById(R.id.grid);
PhotoAdapter adapter = new PhotoAdapter(groups);
grid.setAdapter(adapter);
public List groupPhotosByMonth(List allPhotos) {
Map> map = new LinkedHashMap<>(); // 保持順序
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月", Locale.CHINA);
for (Photo p : allPhotos) {
String key = sdf.format(new Date(p.dateTaken));
map.computeIfAbsent(key, k -> new ArrayList<>()).add(p);
}
List groups = new ArrayList<>();
for (Map.Entry> e : map.entrySet()) {
PhotoGroup g = new PhotoGroup();
g.headerTitle = e.getKey();
g.photos = e.getValue();
groups.add(g);
}
return groups;
}
| 方案 | 優點 | 缺點 |
|---|---|---|
| StickyGridHeaders | 專為 GridView 設計、懸浮頭原生支持、API 簡單 | 庫較老 (2016 年後無更新)、不支持 RecyclerView |
| RecyclerView + Groupie/SectionedRecyclerViewAdapter | 現代架構、靈活、支持多類型 | 需自行實現懸浮頭 (ItemDecoration) |
| 雙層 RecyclerView (外層垂直組、內層 GridLayoutManager) | 無第三方依賴、完全可控 | 懸浮頭需複雜 ItemDecoration、性能調優難 |
新項目**優先用 RecyclerView + SectionedRecyclerViewAdapter** 實現分組列表,GridView 已進入維護模式。StickyGridHeaders 適合快速修舊專案。