如何将 ListView 转换为 GridView

6
以下是我的代码,它可以很好地水平显示列表视图。我该如何将其更改为网格视图?我需要做哪些更改才能将其更改为网格视图?请帮帮我。
public class fifthscreen extends Activity {

int IOConnect = 0;

String _response;
String status;

HorizontalListView listview;
CategoryListAdapter3 cla;

String URL, URL2;
String SelectMenuAPI;
static ArrayList<Long> Category_ID = new ArrayList<Long>();
static ArrayList<String> Category_name = new ArrayList<String>();
static ArrayList<String> Category_image = new ArrayList<String>();
public static String allergen2;

String name;

String url1;

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

    listview = (HorizontalListView) this.findViewById(R.id.listview2);

    cla = new CategoryListAdapter3(fifthscreen.this);
    new TheTask().execute();
}

public class TheTask extends AsyncTask<Void, String, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

    }

    @Override
    protected String doInBackground(Void... arg0) {

        try {


            HttpGet request = new HttpGet(url);
            HttpResponse response = client.execute(request);
            HttpEntity resEntity = response.getEntity();
            _response = EntityUtils.toString(resEntity);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return _response;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);

        try {

            JSONObject json2 = new JSONObject(result);

            status = json2.getString("status");
            if (status.equals("1")) {

                JSONArray school4 = json2.getJSONArray("dish_allergen");
                //
                for (int i = 0; i < school4.length(); i++) {
                    JSONObject object = school4.getJSONObject(i);

                    Category_ID.add((long) i);
                    Category_name.add(object.getString("name"));
                    Category_image.add(object.getString("image"));

                }

            }

            else {

                JSONArray school2 = json2.getJSONArray("data");
                for (int i = 0; i < school2.length(); i++) {
                    JSONObject object = school2.getJSONObject(i);

                    Category_ID.add((long) i);
                    Category_name.add(object.getString("name"));
                }
            }

        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        listview.setAdapter(cla);
    }
}
     }







   public class CategoryListAdapter3 extends BaseAdapter {

private Activity activity;

private AQuery androidAQuery;


public CategoryListAdapter3(Activity act) {
    this.activity = act;
//  imageLoader = new ImageLoader(act);
}

public int getCount() {
    // TODO Auto-generated method stub
    return fifthscreen.Category_ID.size();
}

public Object getItem(int position) {
    // TODO Auto-generated method stub
    return position;
}

public long getItemId(int position) {
    // TODO Auto-generated method stub
    return position;
}

public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    ViewHolder holder;
    androidAQuery = new AQuery(getcontext());
    if(convertView == null){
        LayoutInflater inflater = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.viewitem2, null);
        holder = new ViewHolder();

        convertView.setTag(holder);
    }else{
        holder = (ViewHolder) convertView.getTag();
    }


    holder.txtText = (TextView) convertView.findViewById(R.id.title2);
    holder.imgThumb = (ImageView) convertView.findViewById(R.id.image2);

    holder.txtText.setText(fifthscreen.Category_name.get(position));
    //  imageLoader.DisplayImage(fifthscreen.Category_image.get(position),   
          activity, holder.imgThumb);


     androidAQuery.id(holder.imgThumb).image(fifthscreen.Category_image.get(position), false, 
     false);

    return convertView;
}
private Activity getcontext() {
    // TODO Auto-generated method stub
    return null;
}
static class ViewHolder {
    TextView txtText;
    ImageView imgThumb;
}

          }



             <!---  fifithscreen.xml--->

                  <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
          android:layout_marginLeft="10dp"
          android:layout_marginRight="10dp"
          android:layout_below="@+id/test_button_text5"
         android:orientation="vertical" >

   <com.example.examplecode.HorizontalListView
           android:id="@+id/listview2"
           android:layout_width="wrap_content"
           android:layout_height="120dp"
             android:layout_below="@+id/test_button_text5"

           android:background="#ffffff"/>


      </LinearLayout>




   <!--viewitem2.xml--->



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

   >

  <ImageView
android:id="@+id/image2"
   android:layout_width="90dp"
 android:layout_height="70dp"
  android:scaleType="fitXY"
 android:padding="5dp"

  android:layout_marginLeft="5dp"
   android:layout_marginRight="5dp"

android:src="@drawable/ic_launcher"
/>

<TextView
android:id="@+id/title2"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:textColor="#000"
android:paddingTop="10dp"


android:gravity="center_horizontal"
/>



   </LinearLayout>
5个回答

8
没有任何变化。只需像设置ListView适配器一样设置GridView适配器即可。

我只把ListView改成了GridView,但是它不起作用。 - user2857293
在两个文件中,即 XML 文件和您的活动中? - Khawar Raza

7
我建议您使用RecyclerView代替GridView。
您可能需要参考文档并了解更多相关信息。我在此分享我的代码,其中我使用RecyclerView将网格视图更改为列表视图。
如果您正在使用Android Studio,则可能需要在gradle build中添加依赖项。在我的情况下,我添加如下内容:
dependencies {
    .
    .
    .
    compile 'com.android.support:recyclerview-v7:24.0.0'
}

首先我定义了一个网格单元,用于网格布局

recycler_cell.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

<ImageView
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:id="@+id/imageView2"
    android:layout_alignParentTop="true"
    android:layout_alignParentStart="true"
    android:background="#FF000000"
    android:layout_marginLeft="0dp"
    android:layout_marginRight="0dp"/>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceSmall"
    android:text="Small Text"
    android:id="@+id/textView2"
    android:layout_below="@+id/imageView2"
    android:layout_alig=nParentStart="true"
    android:layout_alignEnd="@+id/imageView2"
    android:gravity="center"/>
</RelativeLayout>

现在我正在定义一个列表行,用于列表布局。

recycler_row.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

<ImageView
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:id="@+id/imageView"
    android:layout_alignParentTop="true"
    android:layout_alignParentStart="true"
    android:background="#FF000000"/>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:text="Large Text"
    android:id="@+id/textView"
    android:layout_alignParentTop="true"
    android:layout_alignBottom="@+id/imageView"
    android:layout_alignParentEnd="true"
    android:layout_toEndOf="@+id/imageView"
    android:gravity="center_vertical"
    android:background="#FF333333"
    android:textColor="#FFF"
    android:padding="10dp"/>
</RelativeLayout>

recycler_view_test.xml 当然,需要定义一个包含RecyclerView的布局。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

<android.support.v7.widget.RecyclerView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/recyclerView"
    android:layout_alignParentLeft="true"
    android:layout_marginLeft="0dp"
    android:layout_alignParentTop="true"
    android:layout_marginTop="0dp"
    android:layout_centerHorizontal="true"
    >
</android.support.v7.widget.RecyclerView>

<Button
    style="?android:attr/buttonStyleSmall"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Change Layout"
    android:id="@+id/btnChange"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:layout_marginBottom="62dp"/>

</RelativeLayout>

我分享了我的代码,但强烈建议您仔细阅读文档和教程,以充分了解RecyclerView。

public class RecyclerViewTest extends AppCompatActivity
{
    final int GRID = 0;
    final int LIST = 1;
    int type;

    RecyclerView recyclerView;
    RecyclerView.LayoutManager gridLayoutManager, linearLayoutManager;
    MyAdapter adapter;

    Button btnChange;


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

        // Display contents in views
        final List<Person> list = new ArrayList<>();
        list.add(new Person("Ariq Row 1"));
        list.add(new Person("Ariq Row 2"));
        list.add(new Person("Ariq Row 3"));

        // Finding views by id
        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        btnChange = (Button) findViewById(R.id.btnChange);

        // Defining Linear Layout Manager
        linearLayoutManager = new LinearLayoutManager(getApplicationContext());
        // Defining Linear Layout Manager (here, 3 column span count)
        gridLayoutManager = new GridLayoutManager(getApplicationContext(), 3);

        //Setting gird view as default view
        type = GRID;
        adapter = new MyAdapter(list, GRID);
        recyclerView.setLayoutManager(gridLayoutManager);
        recyclerView.setAdapter(adapter);

        //Setting click listener
        btnChange.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                if (type == LIST)
                {
                    // Change to grid view
                    adapter = new MyAdapter(list, GRID);
                    recyclerView.setLayoutManager(gridLayoutManager);
                    recyclerView.setAdapter(adapter);
                    type = GRID;
                }

                else
                {
                    // Change to list view
                    adapter = new MyAdapter(list, LIST);
                    recyclerView.setLayoutManager(linearLayoutManager);
                    recyclerView.setAdapter(adapter);
                    type = LIST;
                }
            }
        });

    }
}

//Defining Adapter
class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>
{
    List<Person> list;
    int type;
    final int GRID = 0;
    final int LIST = 1;

    MyAdapter(List<Person> list, int type)
    {
        this.list = list;
        this.type = type;
    }

    // Inflating views if the existing layout items are not being recycled
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
    {
        View itemView;

        if (viewType == GRID)
        {
            // Inflate the grid cell as a view item
            itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_cell, parent, false);
        }

        else
        {
            // Inflate the list row as a view item
            itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_row, parent, false);
        }

        return new ViewHolder(itemView, viewType);
    }

    // Add data to your layout items
    @Override
    public void onBindViewHolder(ViewHolder holder, int position)
    {
        Person person = list.get(position);
        holder.textView.setText(person.name);
    }

    // Number of items
    @Override
    public int getItemCount()
    {
        return list.size();
    }

    // Using the variable "type" to check which layout is to be displayed
    @Override
    public int getItemViewType(int position)
    {
        if (type == GRID)
        {
            return GRID;
        }

        else
        {
            return LIST;
        }
    }

    // Defining ViewHolder inner class
    public class ViewHolder extends RecyclerView.ViewHolder
    {
        TextView textView;
        final int GRID = 0;
        final int LIST = 1;

        public ViewHolder(View itemView, int type)
        {
            super(itemView);
            if (type == GRID)
            {
                textView = (TextView) itemView.findViewById(R.id.textView2);
            }

            else
            {
                textView = (TextView) itemView.findViewById(R.id.textView);
            }
        }
    }
}

// Data Source Class
class Person
{
    String name;

    Person(String name)
    {
        this.name = name;
    }
}

如果您在网格布局中遇到自动适应列数的问题,那么您可能需要查看@s-marks的答案,在其中他扩展了GridLayoutManager类并添加了自己的代码补丁,以及我的修复,如果您开始出现奇怪的列宽。请检查@s-marks's answerfix
在我的情况下,使用他的解决方案,我创建了以下类:
class GridAutofitLayoutManager extends GridLayoutManager
{
    private int mColumnWidth;
    private boolean mColumnWidthChanged = true;

    public GridAutofitLayoutManager(Context context, int columnWidth)
    {
        /* Initially set spanCount to 1, will be changed automatically later. */
        super(context, 1);
        setColumnWidth(checkedColumnWidth(context, columnWidth));
    }

    public GridAutofitLayoutManager(Context context, int columnWidth, int orientation, boolean reverseLayout)
    {
        /* Initially set spanCount to 1, will be changed automatically later. */
        super(context, 1, orientation, reverseLayout);
        setColumnWidth(checkedColumnWidth(context, columnWidth));
    }

    private int checkedColumnWidth(Context context, int columnWidth)
    {
        if (columnWidth <= 0)
        {
            /* Set default columnWidth value (48dp here). It is better to move this constant
            to static constant on top, but we need context to convert it to dp, so can't really
            do so. */
            columnWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 48,
                    context.getResources().getDisplayMetrics());
        }

        else
        {
            columnWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, columnWidth,
                    context.getResources().getDisplayMetrics());
        }
        return columnWidth;
    }

    public void setColumnWidth(int newColumnWidth)
    {
        if (newColumnWidth > 0 && newColumnWidth != mColumnWidth)
        {
            mColumnWidth = newColumnWidth;
            mColumnWidthChanged = true;
        }
    }

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state)
    {
        int width = getWidth();
        int height = getHeight();
        if (mColumnWidthChanged && mColumnWidth > 0 && width > 0 && height > 0)
        {
            int totalSpace;
            if (getOrientation() == VERTICAL)
            {
                totalSpace = width - getPaddingRight() - getPaddingLeft();
            }
            else
            {
                totalSpace = height - getPaddingTop() - getPaddingBottom();
            }
            int spanCount = Math.max(1, totalSpace / mColumnWidth);
            setSpanCount(spanCount);
            mColumnWidthChanged = false;
        }
        super.onLayoutChildren(recycler, state);
    }
}

然后你只需要改变:

gridLayoutManager = new GridLayoutManager(getApplicationContext(), 3);

并使用您的自定义网格布局对象,这里的100是以dp为单位的列宽度

gridLayoutManager = new GridAutofitLayoutManager(getApplicationContext(), 100);

3
你可以像这样做:
对于网格/列表的布局,使用合并:
<?xml version="1.0" encoding="utf-8"?>

<merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >


<ViewStub android:id="@+id/list" 
    android:inflatedId="@+id/showlayout"
    android:layout="@layout/list_view" 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp"/>

<ViewStub android:id="@+id/grid" 
    android:inflatedId="@+id/showlayout"
    android:layout="@layout/grid_view" 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp"/>


</merge>

然后定义列表和网格(以及它们的项目)的布局,并管理它们之间的通道通过填充布局,然后使用像这样的方法来更改当前视图:

private void changeView() {

    //if the current view is the listview, passes to gridview
    if(list_visibile) {
        listview.setVisibility(View.GONE);
        gridview.setVisibility(View.VISIBLE);
        list_visibile = false;
        setAdapters();
    }

    else {
        gridview.setVisibility(View.GONE);                      
        listview.setVisibility(View.VISIBLE);
        list_visibile = true;
        setAdapters();
    }
}

如果需要完整的代码,可以在这篇文章中找到:

http://pillsfromtheweb.blogspot.it/2014/12/android-passare-da-listview-gridview.html


1

只需使用GridView对象而不是Listview,如下:

GridView gridView;
gridView= (GridView) this.findViewById(R.id.gridView1);

CategoryListAdapter3getView方法中,你需要这样做:

convertView = inflater.inflate(R.layout.your_grid_item_leyout, null);

最后,在TheTaskonPostExecute中,像这样做:
gridView.setAdapter(cla);

就是这样。


1
请使用 GridView 而不是以下内容:

Then replace

listview = (HorizontalListView) this.findViewById(R.id.listview2);

to

GridView gridview;
gridview=(GridView) findViewById(R.id.gridview);

一切都没问题,只需使用GridView对象设置适配器即可。完成了。

怎么设置Adapter??如果我只改变这一行 listview =(GridView) findViewById(R.id.listview2); 那么它能正常工作吗?? - user2857293
没问题,只需做出更改并尝试,是的,它会正常工作。如果您发现它有用,请接受并点赞这个答案。 - Pratik Dasa
请将GridView的高度设置为match_parent或fill_parent,并且在item.xml中将LinearLayout的高度和宽度设置为match_parent或fill_parent。 - Pratik Dasa
如果我移除ScrollView,那就没问题了,但是如果保留GridView,它无法完全显示。如何在ScrollView中显示GridView? - user2857293
但是GridView本身就是可滚动的,您不需要使用ScrollView来滚动它。如果您觉得有用,请接受我的答案。 - Pratik Dasa
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接