【问题标题】:How to create custom adapter for custom listview with Hashmap如何使用 Hashmap 为自定义列表视图创建自定义适配器
【发布时间】:2015-08-13 04:15:14
【问题描述】:

我如何为这个 xml 创建一个自定义适配器。有人可以指导我如何创建一个自定义适配器或给我一个关于如何做的示例代码。请帮助我,我需要学习如何创建自定义适配器。请帮助我。提前致谢。

这是我的 MainActivity.java

package com.example.work.listviewadapter;

import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;
import android.widget.SimpleAdapter;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


public class MainActivity extends ActionBarActivity {

private static final String PRODUCTLIST_URL ="http://192.168.56.1/productlist.php";


private ProgressDialog pDialog;

public  static  final JSONParser jParser = new JSONParser();

private static final String GET_PRODUCT = "message";

private static final String GET_ID = "ID";

private static final String GET_BRAND = "Brand";

private static final String GET_CATEGORY = "Category";

private static final String GET_DESCRIPTION = "Description";

private static final String GET_CODE = "Code";

private static final String GET_QUANTITY = "Quantity";

private static final String GET_UNIT = "Unit";

private static final String GET_UNITPRICE = "Unitprice";

private JSONArray order = null;

ListView list;
private ArrayList<HashMap<String, String>> orderlist;

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

new LoadComments().execute();


}


public void updateJSONdata() {

    orderlist = new ArrayList<HashMap<String, String>>();


    JSONObject json = jParser.getJSONFromUrl(PRODUCTLIST_URL);


    try {


        order = json.getJSONArray(GET_PRODUCT);

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

            JSONObject c = order.getJSONObject(i);

            String id = c.getString(GET_ID);

            String brand = c.getString(GET_BRAND);

            String category = c.getString(GET_CATEGORY);

            String description = c.getString(GET_DESCRIPTION);

            String code = c.getString(GET_CODE);

            String quantity = c.getString(GET_QUANTITY);

            String unit = c.getString(GET_UNIT);

            String unitprice = c.getString(GET_UNITPRICE);



            HashMap<String, String> map = new HashMap<String, String>();

            map.put(GET_ID,id);

            map.put(GET_BRAND, brand);

            map.put(GET_CATEGORY, category);

            map.put(GET_DESCRIPTION, description);

            map.put(GET_CODE, code);

            map.put(GET_QUANTITY, quantity);

            map.put(GET_UNIT, unit);

            map.put(GET_UNITPRICE, unitprice);


            orderlist.add(map);

            }

    } catch (JSONException e) {

        e.printStackTrace();

    }

}

private void updateList() {

    //this is for my custom listview

}

final  public class LoadComments extends AsyncTask<Void, Void, Boolean> {

    @Override

    protected void onPreExecute() {

        super.onPreExecute();

        pDialog = new ProgressDialog(MainActivity.this);

        pDialog.setMessage("Loading Order...");

        pDialog.setIndeterminate(false);

        pDialog.setCancelable(true);

        pDialog.show();

    }

    @Override

    protected Boolean doInBackground(Void... arg0) {

        //we will develop this method in version 2

        updateJSONdata();

        return null;

    }

    @Override

    protected void onPostExecute(Boolean result) {

        super.onPostExecute(result);

        pDialog.dismiss();

        //we will develop this method in version 2

        updateList();

    }

}

}

这是我的自定义 ListView。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dip"
android:background="@drawable/list_selector"
>


<TextView
    android:id="@+id/Quantity"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="10000"
    android:textSize="24dip"
    android:textStyle="bold"
    android:layout_alignParentRight="true"
    android:layout_alignParentEnd="true"
    android:layout_marginTop="24dp"
    android:layout_marginRight="51dp"
    >
</TextView>

<TextView
    android:id="@+id/Unit"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Gal."
    android:layout_alignParentRight="true"
    android:layout_marginTop="26dp"
    android:textSize="20dp"
    android:layout_marginRight="15dp"
    />

<TextView
    android:id="@+id/Description"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="10dp"
    android:text="White"
    android:textColor="#040404"
    android:typeface="sans"
    android:textSize="20dip"
    android:textStyle="bold"/>

<TextView
    android:id="@+id/Code"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Wpu-01"
    android:layout_marginTop="2dp"
    android:layout_below="@+id/Description"
    android:layout_marginLeft="10dp"/>
<TextView
    android:id="@+id/Brand"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/Code"
    android:layout_marginLeft="10dp"
    android:layout_marginTop="2dp"
    android:text="Weber"/>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Urethane"
    android:layout_below="@+id/Code"
    android:layout_marginTop="2dp"
    android:layout_toRightOf="@+id/Brand"
    android:layout_marginLeft="5dp"
    android:id="@+id/Category" />
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/Category"
    android:text="P"
    android:layout_marginLeft="12dp"
    android:paddingRight="5dp"
    android:layout_marginTop="2dp"
    android:layout_marginBottom="2dp"
    android:textStyle="italic"
    android:id="@+id/P"
    />
<TextView
    android:id="@+id/Price"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="10000.00"
    android:layout_below="@+id/Brand"
    android:layout_toRightOf="@+id/P"
    android:layout_marginTop="2dp"
    android:layout_marginLeft="2dp"
    />
<TextView
    android:id="@+id/ID"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="11"
    android:layout_alignParentRight="true"
    android:visibility="invisible"
    />
</RelativeLayout>

这是列表视图

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


<EditText
    android:id="@+id/search"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:hint="Search"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentEnd="true"
    android:singleLine="true"/>

<ListView
    android:layout_below="@+id/search"
    android:id="@android:id/list"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="#fff"
    android:divider="#ff5873ff"
    android:dividerHeight="3dp" />

【问题讨论】:

  • ........所以? what is the issue ?
  • 我正在学习如何为我的列表视图使用自定义适配器,但我不知道如何在其中使用 Hashmap 实现自定义适配器。你能帮我根据上面的代码构建自己的适配器吗?
  • 好的,感谢您的帮助
  • 要求我们推荐或查找书籍、工具、软件库、教程或其他场外资源的问题是题外话

标签: android listview


【解决方案1】:

您可以像下面的代码一样设计您的BaseAdapter,也可以使用ViewHolder 模式优化列表视图性能

private class MyAdapter extends BaseAdapter{
    private LayoutInflater mlayoutInflater;

    public MyAdapter(Context context) {
        mlayoutInflater = LayoutInflater.from(context);  //Dynamic layout mapping
    }

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

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        convertView = mlayoutInflater.inflate(R.layout.listitem, null);  //  According to the layout of the document to instantiate view
        TextView tv = (TextView)convertView.findViewById(R.id.textView);
        tv.setText(orderlist.get(position).get(GET_BRAND).toString());
        return convertView;
    }
}

【讨论】:

  • 在你的 Activity 类中
  • 在我的书中,仅将链接作为答案是一个糟糕的答案。即使链接的材料最初回答了问题,链接也会中断并且答案在以后变得毫无价值。至少如果您包含摘要,则答案可以独立存在。请参阅 how to write a good answer 上的新兴常见问题解答
【解决方案2】:

我将使用我制作的自定义适配器作为示例。如果您按照步骤操作并根据您的需要进行调整,它可能会解决您的问题。

当你想自定义ListView时,你必须编写自己的适配器。在这种特殊情况下,我将继承 BaseAdapter 类。

这个自定义适配器将控制我的数据模型,并将数据膨胀到我的ListView 行。

首先,我将创建自定义行的 XML。你可以看下面的代码。

item_mail.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    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">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Test text"
        android:id="@+id/tv_mail"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_centerVertical="true"/>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/iv_icon"
        android:layout_alignParentTop="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:src="@android:drawable/ic_menu_report_image" />
</RelativeLayout>

在这里,我创建了一个显示文本和图像的行。

现在,我将创建我的自定义适配器来处理这个 XML。如下所示。

MailAdapter.java

public class MailAdapter extends BaseAdapter {

    private static final String LOG_TAG = MailAdapter.class.getSimpleName();

    private Context context_;
    private ArrayList<ArrayList<String>> mailitems;

    public MailAdapter(Context context, ArrayList<ArrayList<String>> mailitems) {
        this.context_ = context;
        this.mailitems = mailitems;
    }

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

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            LayoutInflater mInflater = (LayoutInflater)
                    context_.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);

            convertView = mInflater.inflate(R.layout.item_mail, null);
        }

        TextView tv_mail = (TextView) convertView.findViewById(R.id.tv_mail);
        ImageView iv_icon = (ImageView) convertView.findViewById(R.id.iv_icon);

        String mail = mailitems.get(position).get(0);
        String icon = mailitems.get(position).get(1);

        Log.d(LOG_TAG,"Mail: " + mail + " mail_icon: " + icon);

        tv_mail.setText(mail);
        // iv_icon.setImageURI(); Here you can do whatever logic you want to update your image, using URI's, ID's, or something else.

        return convertView;
    }
}

好的。现在我们拥有一切来完成这项工作。在您的 Activity 课程中,执行以下操作:

activity_main.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:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <TextView
        android:text="@string/hello_world"
        android:id="@+id/tv_header"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true" />

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/tv_header">

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Add mail"
            android:id="@+id/button"
            android:layout_gravity="center" />

        <ListView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/listView" />
    </LinearLayout>

</RelativeLayout>

MainActivity.java

public class MainActivity extends ActionBarActivity {

    private int numMail = 1; // Dummy int to create my items with different numbers.

    private MailAdapter mailAdapter; // Your custom adapter.

    private ArrayList<ArrayList<String>> mailItems; // This is going to be your data structure, everytime you change it, call the notifyDataSetChanged() method.

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

        Button bt = (Button) findViewById(R.id.button);
        ListView lv_mail = (ListView) findViewById(R.id.listView);
        mailItems = new ArrayList<>();
        mailAdapter = new MailAdapter(this,mailItems);
        lv_mail.setAdapter(mailAdapter);

        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                addItem(); // The method I'm using to insert the item. Look for it below.
            }
        });
    }

    // Here I'm creating a new ArrayList, and appending it to my 'mailItems' Array. After that, I'm notifying the adapter that my data changed.
    private void addItem() {
        ArrayList<String> mail = new ArrayList<>();

        mail.add(0,"mail " + numMail++);
        mail.add(1,"path_to_image"); // Depending on what you want to do, put your path, URI, or whatever other way you want to store that image data.

        mailItems.add(mail); // Inserting the data on the ArrayList.
        mailAdapter.notifyDataSetChanged(); // Notifying the adapter that my ArrayList was modified.
    }
}

这应该可以解决问题。

你可以阅读更多关于 here 的信息,我发现了一个类似的问题 here,你也可以阅读。

编辑:另一个related question,这可能是一个有趣的阅读。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-27
    • 1970-01-01
    • 2012-02-21
    • 2011-12-31
    • 1970-01-01
    • 2016-04-30
    相关资源
    最近更新 更多