繁体   English   中英

视图未正确包含在单个列表项中

[英]Views not properly contained within single list item

我的目标是从适配器中提取三个JSON Objects ,并在一个list item中将它们显示为三个文本视图。 当前只有一组对象时应如下所示: 在此处输入图片说明

相反,它显示如下:

在此处输入图片说明

我在XML或适配器中看不到任何错误。 (如下所示)是什么导致文本视图像这样拆分成更多列表项的?

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


    <RelativeLayout
        android:layout_width="80dp"
        android:layout_height="wrap_content"
        android:id="@+id/outer"
        android:padding="3dp"
        android:background="#08445e"
        android:layout_toLeftOf="@+id/button"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true">

        <TextView
            android:id="@+id/textViewRoom"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Room "
            android:textColor="#fff"
            android:layout_alignParentLeft="true"/>

        <TextView
            android:id="@+id/textViewTime"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Time: "
            android:layout_alignParentRight="true"
            android:textColor="#fff" />

    </RelativeLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:id="@+id/inner"
        android:background="#d1d1d1"
        android:layout_below="@+id/outer"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_toLeftOf="@+id/button"
        android:layout_toStartOf="@+id/button">

        <TextView
            android:id="@+id/textViewRequest"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:textColor="#000"
            android:textSize="20sp"
            android:layout_centerHorizontal="true" />

    </RelativeLayout>

    <Button
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:background="#dc2f2f"
        android:id="@+id/button"
        android:text="Mark Done"
        android:textColor="#fff"
        android:textAllCaps="false"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:layout_alignBottom="@+id/inner"
        android:layout_alignParentTop="true" />
</RelativeLayout>

MainAdapter.Java:

package com.example.duncan.recyclerviewproject;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;



public class MainAdapter extends BaseAdapter {
    SharedPreferences preferences;

    Context context;
    ArrayList<String> arraylist=new ArrayList<>();

    public MainAdapter(Context context,
                       ArrayList<String>arrayList){
        this.context=context;
        this.arraylist=arrayList;
    }


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

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

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

    public class ViewHolder{
        Button   mark_btn;
        public TextView textViewRoom;
        public TextView textViewRequest;
        public TextView textViewTime;
    }

    @Override
    public View getView(final int position, View row, ViewGroup parent) {
        View convertView=row;
       final ViewHolder holder;
        if(convertView==null) {

            holder=new ViewHolder();
            LayoutInflater infalInflater = (LayoutInflater)
                    context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.custom_layout, null);

            holder.mark_btn= (Button) convertView.findViewById(R.id.button);
            holder.textViewRoom = (TextView) 
convertView.findViewById(R.id.textViewRoom);
            holder.textViewRequest = (TextView) 
convertView.findViewById(R.id.textViewRequest);
            holder.textViewTime = (TextView) 
convertView.findViewById(R.id.textViewTime);
            convertView.setTag(holder);

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

        }


        holder.textViewRoom.setText(arraylist.get(position));
        holder.textViewRequest.setText(arraylist.get(position));
        holder.textViewTime.setText(arraylist.get(position));

        holder.mark_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(context, "Marked complete", 
Toast.LENGTH_SHORT).show();
            }
        });


        return convertView;
    }

    }

MainActivity.java

package com.example.duncan.recyclerviewproject;

import android.app.ProgressDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

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

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

import me.anwarshahriar.calligrapher.Calligrapher;

public class MainActivity extends AppCompatActivity {


    private static final String URL_DATA = 
"https://summerproject17.herokuapp.com/api/request/?format=json";
    private ListView recyclerView;
    private MainAdapter adapter;

    private ArrayList<String> listItems;

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

        recyclerView = (ListView) findViewById(R.id.list);
       /* recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));*/
//is the below line newly added?
        listItems = new ArrayList<>();

        loadRecyclerViewData();

        Calligrapher calligrapher = new Calligrapher(this);
        calligrapher.setFont(this, "elegantluxpro-mager.ttf", true);

    }


    private void loadRecyclerViewData(){
        StringRequest stringRequest = new StringRequest(Request.Method.GET,
                URL_DATA,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        try {
                            JSONObject jsonObject = new JSONObject(response);
                            JSONArray array = 
jsonObject.getJSONArray("results");

                            for(int i = 0; i < array.length(); i++){
                                JSONObject o = array.getJSONObject(i);
                              /*  ListItem item = new ListItem(
                                        o.getString("room"),
                                        o.getString("request"),
                                        o.getString("unixTime")
                                );*/
                                listItems.add(o.getString("room"));
                                listItems.add(o.getString("request"));
                                listItems.add(o.getString("room"));
                            }

                            Log.e("size",""+listItems.size());

                            adapter = new 
MainAdapter(MainActivity.this,listItems);
                            recyclerView.setAdapter((ListAdapter) adapter);

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.e("VOLLEY", error.getMessage());
                    }
                });
        RequestQueue requestQueue = Volley.newRequestQueue(this);
        requestQueue.add(stringRequest);
    }
}

activity_main.xml列表视图部分:

<ListView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/list"
    android:layout_below="@+id/relativeLayout2">

</ListView>

注意:我大约一周前问了一个类似的问题,但这是不同的,因为列表项的结构已更改,并且在此问题中提供了更多详细信息。

我的目标是从适配器中提取3个JSON对象,并在一个列表项中将它们显示为3个文本视图。 当前只有一组对象时应如下所示:

列表适配器被设计为具有1:1映射以及支持它的列表。 因此,据我了解,您的上述方法有些缺陷。 如果希望将三个JSON对象显示为单个列表项的三个TextView ,则需要转换为包含(例如)您定义的类ViewHolder另一个List。 为此,使用自定义适配器查找ListView 不确定ViewHolder为什么是内部类,它可以只是同一文件中的非公共类。

我在XML中看不到任何错误

您的xml布局中似乎有一些冗余。 您可以做的是为列表项定义一个自定义布局,该布局将具有一个RelativeLayout ,该布局具有所有三个文本视图和按钮(类似这样)。

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/list_item"
    android:padding="3dp">

    <TextView
        android:id="@+id/textViewRoom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Room "
        android:textColor="#fff"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"/>

    <Button
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:background="#dc2f2f"
        android:id="@+id/button"
        android:text="Mark Done"
        android:textColor="#fff"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true" />

    <TextView
        android:id="@+id/textViewTime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Time: "
        android:layout_alignParentTop="true"
        android:alignLeft="@id/button"
        android:textColor="#fff" />

    <TextView
        android:id="@+id/textViewRequest"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:textColor="#000"
        android:textSize="20sp"
        android:alignBottom="@id/textViewRoom"
        android:alignLeft="@id/button"
        android:layout_centerHorizontal="true" />


</RelativeLayout>

或者,您可以结合使用LinearLayoutRelativeLayout 但是RelativeLayout没有方向属性,因此您也需要摆脱它。

不知道这是否足以解决您所遇到的特定问题,但希望对您有所帮助。

正如adamarta所说,列表与显示内容之间存在一对一的映射关系。 ArrayList中有1个项目,而ListView中有1个项目。 这样做的常见方法是创建数据模型类。 看起来像这样。

public class RoomItem {
    private String room;
    private String time;
    private String request;

    public RoomItem(String room, String request, String time) {
        this.room = room;
        this.request = request;
        this.time = time;
    }

    public RoomItem() {        
    }

    public String getRoom() {
        return room;
    }

    public void setRoom(String room) {
        this.room = room;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public String getRequest() {
        return request;
    }

    public void setRequest(String request) {
        this.request = request;
    }
}

您的ArrayList声明将像这样更改。

    private ArrayList<RoomItem> listItems;

而且,您还必须更改适配器中使用的ArrayList

另外,在适配器的getView()中,设置如下所示的值

    holder.textViewRoom.setText(arraylist.get(position).getRoom());
    holder.textViewRequest.setText(arraylist.get(position).getRequest());
    holder.textViewTime.setText(arraylist.get(position).getTime());

在MainActivity的loadRecyclerViewData() ,用此替换当前的3个listItems.add(...)

    // create a new data item with the new information
    RoomItem item = new RoomItem(o.getString("room"),
            o.getString("request"),
            o.getString("room"));)

    // then add that item to the list 
    listItems.add(item);

您还可以创建一个空项目,然后添加每个字段(执行此操作或执行上面的代码,而不要同时执行两个操作)

    RoomItem item = new RoomItem();
    item.setRoom(o.getString("room");
    etc.

至于您的布局,如果在预览中看起来还可以,那么可能就可以了。 除非...您要用值替换标签(“房间和时间”)。 我想你不想那样做。 我认为这就是您所需要的。

    <TextView
        android:id="@+id/textViewRoomLabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Room: "
        android:textColor="#fff"
        android:layout_alignParentLeft="true"/>

    <TextView
        android:id="@+id/textViewRoom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="placeholder"
        android:textColor="#fff"
        android:layout_toEndOf="@+id/textViewRoomLabel"
        android:layout_marginStart="10dp"
        />

    <TextView
        android:id="@+id/textViewTimeLabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Time: "
        android:layout_toStartOf="@+id/textViewTime"
        android:layout_marginEnd="10dp"
        android:textColor="#fff" />

    <TextView
        android:id="@+id/textViewTime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="placeholder"
        android:layout_alignParentRight="true"
        android:textColor="#fff" />

我还没有构建和测试它,所以我可能错过了一些小事情,例如需要为新的ArrayList进行更改等,但是我认为这是您所需要的。

暂无
暂无

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

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