簡體   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