[英]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>
或者,您可以結合使用LinearLayout
和RelativeLayout
。 但是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.