简体   繁体   English

如何在自定义对象的android中使用ArrayAdapter

[英]how to use an ArrayAdapter in android of custom objects

How can I use the properties of a custom object in a Listview.如何在 Listview 中使用自定义对象的属性。 If I implement an ArrayAdapter with a list of Strings it displays fine in Listview but when I use a list of custom objects, it just outputs the memory address.如果我用字符串列表实现 ArrayAdapter,它在 Listview 中显示良好,但是当我使用自定义对象列表时,它只输出内存地址。

The code I have up to now:我到目前为止的代码:

ArrayList<CustomObject> allObjects = new ArrayList<>();

allObjects.add("title", "http://url.com"));


  ArrayAdapter<NewsObject> adapter = new ArrayAdapter<NewsObject>(this,
                android.R.layout.simple_list_item_1, android.R.id.text1, allNews);


        // Assign adapter to ListView
        listView.setAdapter(adapter);


        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                Uri uri = Uri.parse( "http://www.google.com" );
                startActivity(new Intent(Intent.ACTION_VIEW, uri));
            }
        });

There is a similar question here but that is not what I need since I just need to have the title show in list view and when they click extract the url.这里有一个类似的问题但这不是我需要的,因为我只需要在列表视图中显示标题,并且当他们单击提取 url 时。

An ArrayAdapter displays the value returned by the toString() method, so you will need to override this method in your custom Object class to return the desired String. ArrayAdapter 显示由toString()方法返回的值,因此您需要在自定义 Object 类中覆盖此方法以返回所需的字符串。 You will also need to have at least a getter method for the URL, so you can retrieve that in the click event.您还需要至少有一个用于 URL 的 getter 方法,以便您可以在 click 事件中检索该方法。

public class NewsObject {
    private String title;
    private String url;

    public NewsObject(String title, String url) {
        this.title = title;
        this.url = url;
    }

    public String getUrl() {
        return url;
    }

    @Override
    public String toString() {
        return title;
    }
    ...
}

In the onItemClick() method, position will be the index in the ArrayList of your custom Objects corresponding to the list item clicked.onItemClick()方法中, position将是与单击的列表项对应的自定义对象的 ArrayList 中的索引。 Retrieve the URL, parse it, and call startActivity() .检索 URL,解析它,然后调用startActivity()

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            NewsObject item = allNews.get(position);
            String url = item.getUrl();
            Uri uri = Uri.parse(url);
            startActivity(new Intent(Intent.ACTION_VIEW, uri));
        }
    });

Please note, I assumed your custom class is NewsObject , as that is what's used with your Adapter example.请注意,我假设您的自定义类是NewsObject ,因为这是您的 Adapter 示例所使用的。

If you want to use a methods of your custom class you need to implement a custor ArrayAdapter class... How to create this?如果你想使用自定义类的方法,你需要实现一个 custor ArrayAdapter 类......如何创建它?

First step第一步

Get your project and create a new class.获取您的项目并创建一个新类。 Then extends class with ArrayAdapter<YourObject>{} and declare inside your atributes that you needs... My example:然后使用ArrayAdapter<YourObject>{}扩展类并在你的属性中声明你需要......我的例子:

public class Room_Adapter extends ArrayAdapter<Room_Object> {

//Declaration of Atributes
private ArrayList<Room_Object> Rooms_Array;
private final Activity context;
private final ListView lvBuinding;

Second第二

Declare a constructor for this class, always you need an Activity and ArrayList, put inside the others if you need... In my case I needs the listview... My example:为这个类声明一个构造函数,你总是需要一个 Activity 和 ArrayList,如果你需要,把它放在其他里面......在我的情况下,我需要列表视图......我的例子:

public Room_Adapter(Activity context, ArrayList<Room_Object> Rooms_Array,ListView lvBuinding) {
    super(context, R.layout.room_layout, Rooms_Array);

    this.context = context;
    this.Rooms_Array = Rooms_Array;
    this.lvBuinding = lvBuinding;
}

The super method nees your activity, custom layout (if you have it) and your array. super 方法需要您的活动、自定义布局(如果有)和您的数组。

Third第三

Declare a static class or create a new one if you have a custom row layout.如果您有自定义行布局,请声明一个静态类或创建一个新类。 My example have a static class:我的例子有一个静态类:

public static class Room_View{

    //Declaration of Atributes
    TextView RoomName;
    ImageView RoomState;
    TextView NoTroubles;

    Button btnRoomRow;

    ImageButton btnShowRoomTasks;
    ImageButton btnAddTasks;

    RelativeLayout RowLayout;
}

Fourth第四

Override method getView.覆盖方法 getView。

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

    //Declaration of Variables
    Room_View rowView; //Custom static class with controls
    LayoutInflater inflator = context.getLayoutInflater();

    if (ConvertView == null) {
        rowView = new Room_View();
        ConvertView = inflator.inflate(R.layout.room_layout,null,true); //Inflate your view with your custom view.


        rowView.RoomName = (TextView) ConvertView.findViewById(R.id.txtvRoom);
        rowView.RoomState = (ImageView) ConvertView.findViewById(R.id.ivRoomState);
        rowView.NoTroubles = (TextView) ConvertView.findViewById(R.id.txtvNoTroubles);

        rowView.btnRoomRow = (Button) ConvertView.findViewById(R.id.btnRoomRow);

        rowView.btnAddTasks = (ImageButton) ConvertView.findViewById(R.id.btnAddTask);
        rowView.btnShowRoomTasks = (ImageButton) ConvertView.findViewById(R.id.btnShowRoomTasks);

        rowView.RowLayout = (RelativeLayout) ConvertView.findViewById(R.id.rowLayout);


        ConvertView.setTag(rowView);
    }
    else
    {
        rowView = (Room_View) ConvertView.getTag();
    }

    //Here custom your control stats
    Room_Object Room = Rooms_Array.get(position);
    rowView.RoomName.setText(Room.getRoomName());

    rowView.NoTroubles.setVisibility(View.INVISIBLE);
    rowView.btnShowRoomTasks.setClickable(true);
    rowView.btnShowRoomTasks.setImageResource(R.drawable.list_3a4b66_50);
    rowView.btnShowRoomTasks.setOnClickListener(OnShowTasksClickListener);

    //This is for add ClickListiner in my buttons...
    rowView.btnAddTasks.setOnClickListener(OnAddTasksClickListener);
    rowView.btnRoomRow.setOnClickListener(OnAddTasksClickListener);

    if(Room.getStatus().equals("Checked")){
        rowView.RowLayout.setBackgroundColor(0xFFC7E6C7);
        rowView.btnShowRoomTasks.setClickable(false);
        rowView.btnShowRoomTasks.setImageResource(R.drawable.list_999999_50);
        rowView.RoomState.setImageResource(R.drawable.check_3ebf4b_50);
    }
    else if(Room.getStatus().equals("Blocked")){
        rowView.RowLayout.setBackgroundColor(0xFFDBC3E5);
        rowView.RoomState.setImageResource(R.drawable.key_9330e0_50);
    }
    else if(Room.getStatus().equals("Dirty")){
        rowView.RowLayout.setBackgroundColor(0xfffceedb);
        rowView.RoomState.setImageResource(R.drawable.icon_housekeeping_3_yellow);
    }
    else if(Room.getStatus().equals("Troubled")){
        rowView.RowLayout.setBackgroundColor(0xFFF4CECD);
        rowView.RoomState.setImageResource(R.drawable.wrench_eb3232_50);

        rowView.NoTroubles.setVisibility(View.VISIBLE);
        try {
            rowView.NoTroubles.setText(Integer.toString(Room.getNoTasks()));
        }
        catch (Exception ex){
            Log.e("-- Error --",ex.getMessage());
        }
    }

    //
    //Pay attention *************************************************
    //

    //Now if you needs to use your custom external class this is the site, now imagine that you need gets string from your custom class in the text view, then:

    //Declare class
    CustomClass object = new CustomClass();

    rowView.(CUSTOM CONTROL FROM YOUR STATIC CLASS).(METHOD OF CONTROL)(object.(CUSTOM METHOD OF YOUR OBJECT));

    //For example If you follows my sample then:
    rowView.NoTroubles.setText(object.getNumberOfTroubles().toString);


    return ConvertView;
}

//Listener Methods for my button controls
private View.OnClickListener OnShowTasksClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        int positionSelected = lvBuinding.getPositionForView((View) v.getParent());
        int totalRooms = lvBuinding.getCount() - 1;
        int actualRoom = totalRooms - positionSelected;

        try{
            //Your code;
        }
        catch (Exception ex){
            Log.e("-- CustomError --", ex.getMessage());
        }
    }
};

private View.OnClickListener OnAddTasksClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        int positionSelected = lvBuinding.getPositionForView((View) v.getParent());
        int totalRooms = lvBuinding.getCount() - 1;
        int actualRoom = totalRooms - positionSelected;

        try{
            //Your code;
        }
        catch (Exception ex){
            Log.e("-- CustomError --", ex.getMessage());
        }
    }
};
}

I think this is that you needs, if you need more info or same advice me and I try to helps you... Good luck, Eduardo!我认为这是您需要的,如果您需要更多信息或同样的建议,我会尽力帮助您...祝您好运,Eduardo!

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                CustomObject obj = allObjects.get(position);
                //Now use obj to access the property
                Uri uri = Uri.parse( "http://www.google.com" );
                startActivity(new Intent(Intent.ACTION_VIEW, uri));
            }
        });

@mike Answer can be short. @mike 答案可能很短。 ArrayAdapter<Item> Item class should override toString() ArrayAdapter<Item> Item类应该覆盖toString()

@Override
    public String toString() {
        return name;
    }

and you done你完成了

您需要覆盖 Adapter 的 getView 以在视图中的某个位置显示单个对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM