[英]Views not properly contained within single list item
My goal is to pull three JSON Objects
from an adapter and display them as three text views in one list item
. 我的目标是从适配器中提取三个JSON Objects
,并在一个list item
中将它们显示为三个文本视图。 It should look like this when only one set of objects in present: 当前只有一组对象时应如下所示:
Instead it's showing this: 相反,它显示如下:
I can't see anything wrong in my XML or adapter. 我在XML或适配器中看不到任何错误。 (Shown Below) What can cause the textviews to split into more list items than desired like this? (如下所示)是什么导致文本视图像这样拆分成更多列表项的?
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: 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 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 list view portion: activity_main.xml列表视图部分:
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/list"
android:layout_below="@+id/relativeLayout2">
</ListView>
Note: I asked a similar question a week or so back but this is different in that the structure of the list items has changed and more details have been provided in this question. 注意:我大约一周前问了一个类似的问题,但这是不同的,因为列表项的结构已更改,并且在此问题中提供了更多详细信息。
My goal is to pull 3 JSON Objects from an adapter and display them as 3 text views in one list item. 我的目标是从适配器中提取3个JSON对象,并在一个列表项中将它们显示为3个文本视图。 It should look like this when only one set of objects in present: 当前只有一组对象时应如下所示:
The list adapter is designed to have a 1 to 1 map with the list that is backing it. 列表适配器被设计为具有1:1映射以及支持它的列表。 Therefore your approach above is somewhat flawed as I understand it. 因此,据我了解,您的上述方法有些缺陷。 If you want three JSON Objects to be displayed as the three TextView
s of a single list item , you need to translate to another List comprised of (for example) the class ViewHolder
which you defined. 如果希望将三个JSON对象显示为单个列表项的三个TextView
,则需要转换为包含(例如)您定义的类ViewHolder
另一个List。 Look up ListView
using custom adapter for this. 为此,使用自定义适配器查找ListView
。 Not sure why ViewHolder
is an internal class, it can simply be a non-public class in the same file. 不确定ViewHolder
为什么是内部类,它可以只是同一文件中的非公共类。
I can't see anything wrong in my XML 我在XML中看不到任何错误
There appear to be some redundancies in your xml layout. 您的xml布局中似乎有一些冗余。 What you could do is define a custom layout for your list item, which would have a single RelativeLayout
that has all the three text views and the button (something like this). 您可以做的是为列表项定义一个自定义布局,该布局将具有一个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>
Or you could use a combination of LinearLayout
and RelativeLayout
. 或者,您可以结合使用LinearLayout
和RelativeLayout
。 But there is no orientation attribute in RelativeLayout
, so you need to get rid of that as well. 但是RelativeLayout
没有方向属性,因此您也需要摆脱它。
Not sure if this is sufficient to solve the specific problem you were struggling with but I hope it helps. 不知道这是否足以解决您所遇到的特定问题,但希望对您有所帮助。
As adamarta says, the there's a 1 to 1 mapping between your list & what's displayed. 正如adamarta所说,列表与显示内容之间存在一对一的映射关系。 1 item in your ArrayList gives you 1 item in your ListView. ArrayList中有1个项目,而ListView中有1个项目。 A common way of doing this is creating a data model class. 这样做的常见方法是创建数据模型类。 It would look like this. 看起来像这样。
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;
}
}
Your ArrayList
declaration would change like this. 您的ArrayList
声明将像这样更改。
private ArrayList<RoomItem> listItems;
And you'll have to change the ArrayList
uses in your adapter as well. 而且,您还必须更改适配器中使用的ArrayList
。
Also, in getView()
in the adapter, set the values like this 另外,在适配器的getView()
中,设置如下所示的值
holder.textViewRoom.setText(arraylist.get(position).getRoom());
holder.textViewRequest.setText(arraylist.get(position).getRequest());
holder.textViewTime.setText(arraylist.get(position).getTime());
In MainActivity, in loadRecyclerViewData()
, replace your 3 current listItems.add(...)
with this. 在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);
You could also create an empty item then add each field (do either this or the above code, not both) 您还可以创建一个空项目,然后添加每个字段(执行此操作或执行上面的代码,而不要同时执行两个操作)
RoomItem item = new RoomItem();
item.setRoom(o.getString("room");
etc.
As for your layout, if it looks OK in the preview, then it's probably OK. 至于您的布局,如果在预览中看起来还可以,那么可能就可以了。 Except... you're replacing the labels (Room & Time) with the values. 除非...您要用值替换标签(“房间和时间”)。 I don't think you want to do that. 我想你不想那样做。 I think this is what you need. 我认为这就是您所需要的。
<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" />
I haven't built and tested this so I may have missed a couple of small things like needing to make changes for the new ArrayList
etc but I think this is what you need. 我还没有构建和测试它,所以我可能错过了一些小事情,例如需要为新的ArrayList
进行更改等,但是我认为这是您所需要的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.