11

I am trying to create a ListView with customized layout. each item in the listView should look like as shown in the item.xml posted below.

in the code, i used

adapter = new ArrayAdapter<T>(getApplicationContext(), R.layout.listi_tems_layout, topicsList);

but it is not working because the constructor of the ArrayAdapter<T> accepts the second parameter as int something like

android.R.layout.simple_list_item_1

, and in my case it is customized layout which is

R.layout.listi_tems_layout

which adapter should i use or how to solve this. thanks

Item:

<?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="wrap_content"
android:orientation="horizontal"
android:weightSum="3">

<TextView 
    android:id="@+id/tvlist_topic"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"/>
<ImageView 
    android:id="@+id/ivList_delete"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:clickable="true"
    android:src="@drawable/delete_icon"
    android:contentDescription="icon to delete item from the Listview"
    android:layout_weight="1"/>
<CheckBox 
    android:id="@+id/cbList_hook"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:checked="false"
    android:layout_weight="1"/>

mainlayout:

<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"
tools:context="${relativePackage}.${activityClass}" >
....
....
....

<ListView 
    android:id="@+id/lvEco_topics"
    android:layout_width="match_parent"
    android:layout_height="470dp"
    android:layout_below="@id/tvEco_topic"
    android:layout_marginTop="30dp"
    android:scrollbars="vertical"
    android:divider="@android:drawable/alert_light_frame"></ListView>
<Button 
    android:id="@+id/btEco_save"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@id/lvEco_topics"
    android:gravity="center"
    android:text="Save"/>

code:

public class MainActivity extends Activity {

private ArrayList<String> topicsList;
private ListAdapter adapter;

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

    topicsList = new ArrayList<String>();
    topicsList.add("topic1");
    topicsList.add("topic2");
    topicsList.add("topic3");
    topicsList.add("topic4");
    topicsList.add("topic5");
    topicsList.add("topic6");

    adapter = new ArrayAdapter<T>(getApplicationContext(), R.layout.listi_tems_layout, topicsList);
Andy
  • 49,085
  • 60
  • 166
  • 233
rmaik
  • 1,076
  • 3
  • 15
  • 48
  • what problem getting using `adapter = new ArrayAdapter(getApplicationContext(), R.layout.listi_tems_layout, topicsList);` ? – ρяσѕρєя K Jan 28 '15 at 12:58
  • @ρяσѕρєяK the problem i am getting is 2 the constructor is undefined" – rmaik Jan 28 '15 at 13:04
  • @MD i tried your suggestion, but i receive a warnin says 2Type safety: The constructor ArrayAdapter(Context, int, List) belongs to the raw type ArrayAdapter. References to generic type ArrayAdapter should be parameterized" – rmaik Jan 28 '15 at 13:05
  • 1
    create adapter as `ArrayAdapter adapter = new ArrayAdapter(MainActivity.this, R.layout.listi_tems_layout, topicsList);` and see my answer for other changes – ρяσѕρєя K Jan 28 '15 at 13:07

5 Answers5

8

ArrayAdapter accepts the second parameter as int something like android.R.layout.simple_list_item_1

When not customizing getView method of ArrayAdapter then custom layout require one TextView with android:id="@android:id/text1" id and show value in one TextView.

To run application with current code add android:id="@android:id/text1" for TextView in R.layout.listi_tems_layout layout.

Because R.layout.listi_tems_layout layout contains other views also with TextView so create custom Adapter by extending ArrayAdapter class to access other views also.

See following example:Custom ArrayAdapter for a ListView (Android)

ρяσѕρєя K
  • 132,198
  • 53
  • 198
  • 213
7

I'm not sure if it's still relevant, from the source ArrayAdapter seem to have constructor that accept textview resource in 3rd parameter, not sure if it's juts newly added in 2017 :D,

ArrayAdapter adapter = new ArrayAdapter<>(context,YourCustomLayoutID,TextViewIDinYourLayout,ListData);

and from the source, if you didn't supply textview layout id, it will assume that the whole view is a textview, so I think it's possible to use custom view without extending/creating new adapter (I know, I hate to create one myself), but you need to provide textview used for the text

user5962153
  • 154
  • 2
  • 9
4

create a class and extends with base adapter like this and then set this adapter

import java.util.ArrayList;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.example.test.R;
import com.itoks.model.ClientDetails;

public class ClientListAdapter extends BaseAdapter {
    // ArrayList<String> name, company, email, id, status;
    ArrayList<ClientDetails> clientArrayList;
    Context c;

    public ClientListAdapter(Context c, ArrayList<ClientDetails> list) {
        clientArrayList = list;
        this.c = c;

    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return clientArrayList.size();
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return clientArrayList.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        View row = null;
        LayoutInflater inflater = (LayoutInflater) c
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if (convertView == null) {
            row = inflater.inflate(R.layout.listview_item_clients, parent,
                    false);
        } else {
            row = convertView;
        }
        ClientDetails detail = clientArrayList.get(position);
        TextView name = (TextView) row.findViewById(R.id.tvClientFullName);
        name.setText(detail.name);
        TextView email = (TextView) row.findViewById(R.id.tvClientEmail);
        email.setText(detail.email);
        TextView id = (TextView) row.findViewById(R.id.tvClientID);
        id.setText("ID : " + detail.id);
        TextView company = (TextView) row
                .findViewById(R.id.tvClientCompanyName);
        company.setText(detail.company);
        TextView status = (TextView) row.findViewById(R.id.tvClientStatus);
        status.setText("Status:" + detail.status);
        return row;
    }

}
Gopal Singh Sirvi
  • 4,539
  • 5
  • 33
  • 55
  • getItem returns null ?? – 2Dee Jan 28 '15 at 13:03
  • No matter you can access that item with your customized ArrayList with the position. – Gopal Singh Sirvi Jan 28 '15 at 13:05
  • Still a bad practice. – 2Dee Jan 28 '15 at 13:06
  • return clientArrayList.get(position); of course ... You should also protect against null list in constructor – 2Dee Jan 28 '15 at 13:07
  • But in this project I didn't need to access that item directly. Thats why I am returning null here. – Gopal Singh Sirvi Jan 28 '15 at 13:09
  • If another dev uses that adapter, he has no way to know you didn't implement that method. If you really don't want to implement it correctly, the correct way would be throwing NotImplementedException to inform user of that class that the method is not implemented. I also recommend you read this answer about BaseAdapter vs ArrayAdapter, since you seem to worry about having to implement too many methods : http://stackoverflow.com/a/16796355/1178337 – 2Dee Jan 28 '15 at 13:11
  • for live example kindly go through **https://www.youtube.com/watch?v=UMSdD05NVYQ** – Dharmbir Singh Feb 28 '17 at 04:27
2

As I understand you. You are trying to have custom layout in ArrayAdapter. It's not possible. Yout need to write your own custom adapter extending arrayAdapter class where you define how to deal with your custom layout using your topicsList. Something like this:

public class ChatUserAdapter extends ArrayAdapter<UserChat> {

private Activity context;
private List<UserChat> userList;
private int ilayout;

public ChatUserAdapter(Activity context, int layout, List<UserChat> userList) {
    super(context, layout, userList);
    this.context = context;
    this.userList = userList;
    this.ilayout = layout;
}

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

static class ViewHolder {
    public TextView tvEmail;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder viewHolder;
    View rowView = convertView;
    if (rowView == null) {

        LayoutInflater layoutInflater = context.getLayoutInflater();
        rowView = layoutInflater.inflate(ilayout, null, true);
        viewHolder = new ViewHolder();
        viewHolder.tvEmail = (TextView) rowView.findViewById(R.id.tv_email);
        rowView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) rowView.getTag();
    }

    UserChat item = userList.get(position);
    viewHolder.tvEmail.setText(item.getName() + " " + item.getSurname());
    return rowView;
}
}
Karol Żygłowicz
  • 2,442
  • 2
  • 26
  • 35
-1

Please create your own ItemAdapter which extends ArrayAdapter<>.

public class ItemAdapter extends ArrayAdapter<Item> {
private int resource;
private List<Item> items;

public ItemAdapter(Context context, int resource, List<Item> items) {
    super(context, resource, items);
    this.resource = resource;
    this.items = items;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    LinearLayout itemView;
    final Item item = getItem(position);

    if (convertView == null) {
        itemView = new LinearLayout(getContext());

        LayoutInflater layoutInflater = LayoutInflater.from(getContext());
        layoutInflater.inflate(resource, itemView, true);
    }
    else {
        itemView = (LinearLayout) convertView;
    }

And load your item.xml in MainActivity onCreate()

public class MainActivity{
    private List<Item> items;
    private ItemAdapter itemAdapter;
    @Override
      protected void onCreate(Bundle savedInstanceState) {
      itemAdapter = new ItemAdapter(this, R.layout.item, items);
ChihWei
  • 269
  • 1
  • 4