GridView Gallery |由标题分隔的图像

时间:2017-05-19 11:35:09

标签: android gridview header dialog gallery

我在对话框中使用gridView库构建应用程序。所有画廊都很好但现在我想从另一个画廊分开一些照片(需要创建某种类型的标题)。例如,我在我的SD卡文件夹上有一些名为1v1.jpg / 1v2.jpg / 1v3.jpg / 2v1.jpg / 2v2.jpg的照片,现在我想在我的gridView库中显示它(让我们来看看)假设它有2列)

应该如何看待:

1

1v1.jpg 1v2.jpg

1v3.jpg

2

2v1.jpg 2v2.jpg

现在我只有照片的画廊

一些代码:

GridAdapter:

public class GridAdapter extends BaseAdapter {

    Context mContext;
    ArrayList<File> listFiles;

    public GridAdapter(Context context, ArrayList<File> files) {

        this.mContext = context;
        this.listFiles = files;

    }

    @Override
    public int getCount() {
        return listFiles.size();
    }

    @Override
    public Object getItem(int position) {
        return listFiles.get(position);
    }

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

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

        if(convertView == null)
        {
                convertView = LayoutInflater.from(mContext).inflate(R.layout.my_grid, parent, false);
        }

        final ImageView iv = (ImageView) convertView.findViewById(R.id.imageView);

       Glide.with(mContext)
                .load(listFiles.get(position).getAbsolutePath()) //path to picture
                .into(iv);


        return convertView;
    }

} //end of gridadapter

//休息代码

public ArrayList<File> photoList;
public ArrayList<String> albumList;

photoList = imageReader(photoDir);
albumList = albumReader(photoDir);

//function to get all file paths (works)
    private ArrayList<File> imageReader(File root)
    {
        ArrayList<File> a = new ArrayList<>();
        File[] files = root.listFiles();
        for (File file : files) {
            if (file.isDirectory()) {                 
                a.addAll(imageReader(file));
            } else {
                if (file.getName().length() == 14)
                {
                    a.add(file);
                }
            }
        }
        return a;
    }
        //function to get all headers name (works)
        private ArrayList<String> albumReader(File root)
        {
            ArrayList<String> pages = new ArrayList<>();
            File[] files = root.listFiles();
            for (File file : files)
            {
                String photoName;
                String temp = "";
                photoName =  file.getName();
                if(photoName.length()==14)
                {
                    photoName = photoName.substring(0, 4);        
                    if (!temp.equals(photoName))
                    {
                        if(pages.isEmpty() || !pages.contains(photoName))
                        {
                            pages.add(photoName);
                            temp = photoName;
                        }
                        else
                        {
                            break;
                        }
                    }
                }

            }

            return pages;
        }

public void firstChoiceDialogGallery() {

        inflater = this.getLayoutInflater();

        // Dialog layout
        v = inflater.inflate(R.layout.dialog_choice, null);

        // Get gridView from dialog_choice
        gV = (GridView) v.findViewById(R.id.gridView);

        // GridAdapter (Pass context and files list)
        GridAdapter adapter = new GridAdapter(this, photoList);



        // Set adapter
        gV.setAdapter(adapter);

        final AlertDialog.Builder builder2 = new AlertDialog.Builder(this);
        builder2.setTitle("MY GALLERY");

        builder2.setView(v);
        builder2.setPositiveButton("NEXT", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

            }
        }).setNegativeButton("BACK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

            }
        });

        builder2.setCancelable(false);
        final AlertDialog dialog = builder2.create();
        dialog.show();
    }

XMLs: grid_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <ImageView
        android:layout_width="@integer/width"
        android:layout_height="@integer/height"
        android:adjustViewBounds="true"
        android:id="@+id/imageView"
        android:layout_margin="5dp"
        android:layout_centerVertical="true"
        android:layout_alignParentEnd="true" />

</RelativeLayout>

grid.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/dialog_choice"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <GridView
        android:id="@+id/gridView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:numColumns="@integer/column_count"
        android:clickable="true"/>


</RelativeLayout>

如你所见,我写了一个函数来获取标题名称,画廊的作品,但现在我没有想法如何将这些名字放在特定的地方以及如何做到这一点。 我正在考虑把它放到我现有的适配器上,但它不起作用

P.S我读到了关于StickyGridHeaders的信息,所以在这里给lib源链接不回答,因为已经知道了。问题是我不确定这是我想要的+我不知道如何实现它现有代码

4 个答案:

答案 0 :(得分:2)

需要创建名为item_row.xml的自定义适配器或任何您想要的

  

item_row.xml

布局中的

定义了您想要的视图,在您的情况下,您可以看到我看到的图像视图和文本视图:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="105dp"
android:layout_height="120dp">
<ImageView
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:id="@+id/ImgItem"
    android:layout_marginTop="7dp"
    android:layout_gravity="center"/>
<TextView
    android:id="@+id/textItem"
    android:layout_width="120dp"
    android:layout_height="25dp"
    android:textSize="16sp"
    android:layout_marginBottom="3dp"
    android:layout_gravity="center"
    android:textColor="#182b4b"
    android:gravity="center" />
</LinearLayout>

现在,创建你的适配器类,在这里你指出适配器来膨胀刚刚创建的视图(item_row,xml):

  

rowitem.java

确保从

延伸
  

ArrayAdapter

public class rowitem extends ArrayAdapter<String> {

private final Activity context;
private String[] nameItem;
private Bitmap[] iconsItem;

public rowitem(Activity context, String[] nameItem, Bitmap[] iconsItem) {
    super(context, R.layout.adapter_sketchmenuside, nameItem);
    // TODO Auto-generated constructor stub

    this.context = context;
    this.nameItem = nameItem;
    this.iconsItem = iconsItem;
}

public View getView(int posicion, View view, ViewGroup parent){
    LayoutInflater inflater = context.getLayoutInflater();
//inflate the item_row.xml view
    View rowView = inflater.inflate(R.item_row,null, 
true);

    TextView txtTitle = (TextView) rowView.findViewById(R.id.textItem);
    ImageView imageView = (ImageView) rowView.findViewById(R.id.ImgItem);

// Do your stuff
}

作为您的最后一步,将新的自定义适配器设置为gridview,无论您在哪里声明它:

GridView myGrid = (GridView) view.findViewById(R.id.GrdCategory);

//in wherever you want, set the adapter:
myGrid.setAdapter(new rowitem(getActivity(), 
               namesArray, //here you send an Array with Strings for the names of the images
               imgArray, // here you send an array with the images you want to load
));

那样做,有任何问题让我知道,如果正确请标记为正确答案。快乐的编码!

答案 1 :(得分:1)

我想您需要使用不同的项目视图类型。基于此,您可以为标题和基本项配置不同的布局。这应该适用于Recycler,基于RecyclerView doc布局管理器 - StaggeredGridLayoutManager

答案 2 :(得分:0)

有很好的方法来实现这种行为/布局。尝试这样的事情:

sectionableAdapter:

public abstract class SectionableAdapter extends BaseAdapter {

public static final int MODE_VARY_WIDTHS = 0;
public static final int MODE_VARY_COUNT = 1;

private LayoutInflater inflater;
private int rowResID;
private int headerID;
private int itemHolderID;
private int colCount;
private int sectionsCount;
private int resizeMode;
private ViewGroup measuredRow;

public SectionableAdapter(LayoutInflater inflater, int rowLayoutID, int headerID, int itemHolderID)
{
    this(inflater, rowLayoutID, headerID, itemHolderID, MODE_VARY_WIDTHS);
}

/**
 * Constructor.
 * @param inflater inflater to create rows within the grid.
 * @param rowLayoutID layout resource ID for each row within the grid.
 * @param headerID resource ID for the header element contained within the grid row.
 * @param itemHolderID resource ID for the cell wrapper contained within the grid row. This View must only contain cells.
 */
public SectionableAdapter(LayoutInflater inflater, int rowLayoutID, int headerID, int itemHolderID, int resizeMode)
{
    super();
    this.inflater = inflater;
    this.rowResID = rowLayoutID;
    this.headerID = headerID;
    this.itemHolderID = itemHolderID;
    this.resizeMode = resizeMode;
    // Determine how many columns our row holds.
    View row = inflater.inflate(rowLayoutID, null);
    if (row == null)
        throw new IllegalArgumentException("Invalid row layout ID provided.");
    ViewGroup holder = (ViewGroup)row.findViewById(itemHolderID);
    if (holder == null)
        throw new IllegalArgumentException("Item holder ID was not found in the row.");
    if (holder.getChildCount() == 0)
        throw new IllegalArgumentException("Item holder does not contain any items.");
    colCount = holder.getChildCount();
    sectionsCount = getSectionsCount();
}

/**
 * Returns the total number of items to display.
 */
protected abstract int getDataCount();

/**
 * Returns the number of sections to display.
 */
protected abstract int getSectionsCount();

/**
 * @param index the 0-based index of the section to count.
 * @return the number of items in the requested section.
 */
protected abstract int getCountInSection(int index);

/**
 * @param position the 0-based index of the data element in the grid.
 * @return which section this item belongs to.
 */
protected abstract int getTypeFor(int position);

/**
 * @param section the 0-based index of the section.
 * @return the text to display for this section.
 */
protected abstract String getHeaderForSection(int section);

/**
 * Populate the View and attach any listeners.
 * @param cell the inflated cell View to populate.
 * @param position the 0-based index of the data element in the grid.
 */
protected abstract void bindView(View cell, int position);

/**
 * Perform any row-specific customization your grid requires. For example, you could add a header to the
 * first row or a footer to the last row.
 * @param row the 0-based index of the row to customize.
 * @param convertView the inflated row View.
 */
protected void customizeRow(int row, View rowView)
{
    // By default, does nothing. Override to perform custom actions.
}

@Override
public int getCount()
{
    int totalCount = 0;
    for (int i = 0; i < sectionsCount; ++i)
    {
        int count = getCountInSection(i);
        if (count > 0)
            totalCount += (getCountInSection(i)-1) / colCount + 1;
    }
    if (totalCount == 0)
        totalCount = 1;
    return totalCount;
}

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

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    int realPosition = 0;
    int viewsToDraw = 0;
    int rows = 0;
    int totalCount = 0;
    for (int i = 0; i < sectionsCount; ++i)
    {
        int sectionCount = getCountInSection(i);
        totalCount += sectionCount;
        if (sectionCount > 0 && position <= rows + (sectionCount - 1) / colCount)
        {
            realPosition += (position - rows) * colCount;
            viewsToDraw = (int)(totalCount - realPosition);
            break;
        }
        else
        {
            if (sectionCount > 0)
            {
                rows += (int)((sectionCount - 1) / colCount + 1);
            }
            realPosition += sectionCount;
        }
    }
    if (convertView == null)
    {
        convertView = inflater.inflate(rowResID, parent, false);
        if (measuredRow == null && resizeMode == MODE_VARY_COUNT)
        {
            measuredRow = (ViewGroup)convertView;
            // In this mode, we need to learn how wide our row will be, so we can calculate
            // the number of columns to show.
            // This listener will notify us once the layout pass is done and we have our
            // measurements.
            measuredRow.getViewTreeObserver().addOnGlobalLayoutListener(layoutObserver);
        }
    }
    int lastType = -1;
    if (realPosition > 0)
        lastType = getTypeFor(realPosition-1);
    if (getDataCount() > 0)
    {
        TextView header = (TextView)convertView.findViewById(headerID);
        int newType = getTypeFor(realPosition);
        if (newType != lastType)
        {
            header.setVisibility(View.VISIBLE);
            header.setText(getHeaderForSection(newType));

        }
        else
        {
            header.setVisibility(View.GONE);
        }
    }
    customizeRow(position, convertView);

    ViewGroup itemHolder = (ViewGroup)convertView.findViewById(itemHolderID);
    for (int i = 0; i < itemHolder.getChildCount(); ++i)
    {
        View child = itemHolder.getChildAt(i);
        if (i < colCount && i < viewsToDraw && child != null)
        {
            bindView(child, realPosition + i);
            child.setVisibility(View.VISIBLE);
        }
        else if (child != null)
        {
            child.setVisibility(View.INVISIBLE);
        }
    }
    return convertView;
}

private ViewTreeObserver.OnGlobalLayoutListener layoutObserver = new ViewTreeObserver.OnGlobalLayoutListener() {

    // The better-named method removeOnGlobalLayoutListener isn't available until a later API version.
    @SuppressWarnings("deprecation")
    @Override
    public void onGlobalLayout() {
        if (measuredRow != null)
        {
            int rowWidth = measuredRow.getWidth();
            ViewGroup childHolder = (ViewGroup)measuredRow.findViewById(itemHolderID);
            View child = childHolder.getChildAt(0);
            int itemWidth = child.getWidth();
            if (rowWidth > 0 && itemWidth > 0)
            {
                colCount = rowWidth / itemWidth;
                // Make sure this listener isn't called again after we layout for the next time.
                measuredRow.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                // The grid will now update with the correct column count.
                notifyDataSetChanged();
            }
        }
    }
};

}

BookcaseAdapter:

public class BookcaseAdapter extends SectionableAdapter implements
    View.OnClickListener {

// For simplicity, we hard-code the headers and data. In an actual app, this
// can come from the network, the filesystem, SQLite, or any of the 
// usual suspects.
static final String[] AUTHORS = new String[] { "Roberto Bola–o",
        "David Mitchell", "Haruki Murakami", "Thomas Pynchon" };
private static final String[][] BOOKS = new String[][] {
        { "The Savage Detectives", "2666" },
        { "Ghostwritten", "number9dream", "Cloud Atlas",
                "Black Swan Green", "The Thousand Autumns of Jacob de Zoet" },
        { "A Wild Sheep Chase",
                "Hard-Boiled Wonderland and the End of the World",
                "Norwegian Wood", "Dance Dance Dance",
                "South of the Border, West of the Sun",
                "The Wind-Up Bird Chronicle", "Sputnik Sweetheart",
                "Kafka on the Shore", "After Dark", "1Q84" },
        { "V.", "The Crying of Lot 49", "Gravity's Rainbow", "Vineland",
                "Mason & Dixon", "Against the Day", "Inherent Vice" } };

private Activity activity;

public BookcaseAdapter(Activity activity, LayoutInflater inflater,
        int rowLayoutID, int headerID, int itemHolderID, int resizeMode) {
    super(inflater, rowLayoutID, headerID, itemHolderID, resizeMode);
    this.activity = activity;
}

@Override
public Object getItem(int position) {
    for (int i = 0; i < BOOKS.length; ++i) {
        if (position < BOOKS[i].length) {
            return BOOKS[i][position];
        }
        position -= BOOKS[i].length;
    }
    // This will never happen.
    return null;
}

@Override
protected int getDataCount() {
    int total = 0;
    for (int i = 0; i < BOOKS.length; ++i) {
        total += BOOKS[i].length;
    }
    return total;
}

@Override
protected int getSectionsCount() {
    return BOOKS.length;
}

@Override
protected int getCountInSection(int index) {
    return BOOKS[index].length;
}

@Override
protected int getTypeFor(int position) {
    int runningTotal = 0;
    int i = 0;
    for (i = 0; i < BOOKS.length; ++i) {
        int sectionCount = BOOKS[i].length;
        if (position < runningTotal + sectionCount)
            return i;
        runningTotal += sectionCount;
    }
    // This will never happen.
    return -1;
}

@Override
protected String getHeaderForSection(int section) {
    return AUTHORS[section];
}

@Override
protected void bindView(View convertView, int position) {
    String title = (String) getItem(position);
    TextView label = (TextView) convertView
            .findViewById(R.id.bookItem_title);
    label.setText(title);
    convertView.setOnClickListener(this);
}

@Override
public void onClick(View v) {
    Intent i = new Intent(Intent.ACTION_SEARCH);
    TextView label = (TextView) v.findViewById(R.id.bookItem_title);
    String text = label.getText().toString();
    i.putExtra(SearchManager.QUERY, text);
    activity.startActivity(i);
}

}

SectionedGridActivity:

  public class SectionedGridActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sectioned_grid);

    ListView list = (ListView) findViewById(R.id.sectionedGrid_list);
    // Switch between these to see the two different types of resizing available.
    BookcaseAdapter adapter = new BookcaseAdapter(this,
            getLayoutInflater(), R.layout.book_row, R.id.bookRow_header,
            R.id.bookRow_itemHolder, SectionableAdapter.MODE_VARY_WIDTHS);
//      BookcaseAdapter adapter = new BookcaseAdapter(this,
//              getLayoutInflater(), R.layout.book_row_vary_columns, R.id.bookRow_header,
//              R.id.bookRow_itemHolder, SectionableAdapter.MODE_VARY_COUNT);
    list.setAdapter(adapter);
    list.setDividerHeight(0);
}

}

所有这些布局都适用于它:

activity_sectioned_grid.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
 >

<ListView
    android:id="@+id/sectionedGrid_list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:listSelector="@android:color/transparent"
    />

</RelativeLayout>

book_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="200dp"
android:layout_weight="1"
android:orientation="vertical" 
android:background="@drawable/gradients"
android:layout_margin="8dp"
>
<TextView
    android:id="@+id/bookItem_title"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:textColor="#ffffff"
    android:padding="8dp"
    />
</LinearLayout>

book_item_vary_columns.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="190dp"
android:layout_height="190dp"
android:orientation="vertical" 
android:padding="8dp"
>
<TextView
    android:id="@+id/bookItem_title"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:textColor="#ffffff"
    android:padding="8dp"
    android:background="@drawable/gradients"
    />
</LinearLayout>

book_row.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView 
    android:id="@+id/bookRow_header"
    style="@android:style/TextAppearance.Holo.Large"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="8dp"
    android:visibility="gone"
    />
<LinearLayout 
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:id="@+id/bookRow_itemHolder"
    >
    <include layout="@layout/book_item"/>
    <include layout="@layout/book_item"/>
</LinearLayout>

</LinearLayout>

book_row_vary_columns.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView 
    android:id="@+id/bookRow_header"
    style="@android:style/TextAppearance.Holo.Large"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="8dp"
    android:visibility="gone"
    />
<LinearLayout 
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:id="@+id/bookRow_itemHolder"
    >
    <include layout="@layout/book_item_vary_columns"/>
    <include layout="@layout/book_item_vary_columns"/>
    <include layout="@layout/book_item_vary_columns"/>
    <include layout="@layout/book_item_vary_columns"/>
    <include layout="@layout/book_item_vary_columns"/>
    <include layout="@layout/book_item_vary_columns"/>
    <include layout="@layout/book_item_vary_columns"/>
    <include layout="@layout/book_item_vary_columns"/>
    <include layout="@layout/book_item_vary_columns"/>
    <include layout="@layout/book_item_vary_columns"/>
</LinearLayout>

</LinearLayout>

请注意,此代码不是我的,它只是适合这个问题,我之前研究过这些信息。尝试搜索谷歌的分区网格 - 你会发现一个演示apk。

答案 3 :(得分:0)

好的,对于这样的布局,您需要基本上不同的网格视图用于不同的图像部分,例如

GridView 1 for 1v1.png 1v2.png等等

GridView 2 for 2v1.png 2v2.png等等

然后可以通过Textview标题分隔这些网格视图。

因此,要实现此功能,您可以将父布局设为Listview(而不是您正在使用的gridview)。

在此列表视图中, ItemRow 可以在其下方包含Textview和gridview。

因此,Listview将根据您的需要填写精确的布局。如果您不想要任何其他库,例如如上面的答案所示,它可以很容易地完成。

所以布局将是:

父布局:

 $(your element).att('att name','att variabel);

此列表视图的项目将包含:

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
    <ListView
        android:id="@+id/lv_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    </RelativeLayout>

最后填充图像的gridview, 第三个布局是:

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

<GridView
    android:id="@+id/gv_items"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:numColumns="2" />