String Array With Custom Adapters

时间:2015-07-28 15:44:23

标签: android android-adapter android-adapterview

Can we use String array with custom adapter and data should be display in Listview?

I mean something like that

 String [] s= {"cars","bike","train"}; 

Now how this string array will attach with Custom adapter and how data will show in the ListView.

I know this is easy with ArrayList.

But I want to do it with simple String Array.

1 个答案:

答案 0 :(得分:3)

Well, you can use a custom adapter for that. But you could also use the ArrayAdapter class if you just want to show text on your ListView.

But, if for whatever reason you want to create a custom adapter, try the following...

In this particular case I'm subclassing the BaseAdapter class.

This custom adapter will take hold of my data model, and will inflate the data to my ListView rows.

First, I'll create the XML of my custom row. You can see the code below.

item.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"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_centerVertical="true"/>

</RelativeLayout>

Here I've created a row that displays a text.

Now, I'll create my custom adapter to handle this XML. As you can see below.

MyAdapter.java

public class MyAdapter extends BaseAdapter {

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

    private Context context_;
    private ArrayList<String> items;

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

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

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

    @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 = (TextView) convertView.findViewById(R.id.tv);

        String text = items.get(position);

        Log.d(LOG_TAG,"Text: " + text);

        tv.setText(text);

        return convertView;
    }
}

Ok. Now we have everything to make this work. In your Activity class, do something like that:

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 item"
            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 numItem = 1; // Dummy int to create my items with different numbers.

    private MyAdapter myAdapter; // Your custom adapter.

    private ArrayList<String> items; // This is going to be your data structure, every time 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 = (ListView) findViewById(R.id.listView);
        items = new ArrayList<>();
        myAdapter = new MyAdapter(this,items);
        lv.setAdapter(myAdapter);

        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.
            }
        });
    }

    private void addItem() {
        items.add("Text " + numItem++);

        mailAdapter.notifyDataSetChanged(); // Notifying the adapter that my ArrayList was modified.
    }
}

This should do the trick.


From what you told me, you want to use a String array instead of a ArrayList<String>. Well, change the adapter to the following.

MyAdapter.java

public class MyAdapter extends BaseAdapter {

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

    private Context context_;
    private String[] items;

    public MyAdapter(Context context, String[] items) {
        this.context_ = context;
        this.items = items;
    }

    @Override
    public int getCount() {
        return items.length;
    }

    @Override
    public Object getItem(int position) {
        return items[position];
    }

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

    // Rest of the code... Same as before.
}

MainActivity.java

public class MainActivity extends ActionBarActivity {

    private MyAdapter myAdapter; // Your custom adapter.

    private String[] items;

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

        Button bt = (Button) findViewById(R.id.button);
        ListView lv = (ListView) findViewById(R.id.listView);
        items = {"Whatever","String","You","Like"};
        myAdapter = new MyAdapter(this,items);
        lv.setAdapter(myAdapter);
    }
}

The problem with this approach: Your adapter will have a fixed size, which will be the size of your String array once you create it. And you won't be able to make it bigger, unless you create another adapter with a different String array.

This question discusses this matter.