我的目标是从适配器中提取三个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>
注意:我在一周左右的时间里问了一个类似的问题,但不同之处在于列表项的结构已经改变,并且在这个问题中提供了更多细节。
答案 0 :(得分:2)
我的目标是从适配器中提取3个JSON对象,并在一个列表项中将它们显示为3个文本视图。当现在只有一组对象时,它应该看起来像这样:
列表适配器设计为具有1到1的映射,其中包含支持它的列表。因此,根据我的理解,您的上述方法存在一些缺陷。如果您希望将三个JSON对象显示为单个列表项的三个TextView
,则需要转换为另一个由(例如)类{{1}组成的列表你定义的。为此使用自定义适配器查找ViewHolder
。不确定ListView
为什么是内部类,它可以只是同一文件中的非公共类。
我在XML中看不到任何错误
您的xml布局中似乎存在一些冗余。你可以做的是为你的列表项定义一个自定义布局,它有一个ViewHolder
,它包含所有三个文本视图和按钮(类似这样)。
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
中没有方向属性,所以你也需要摆脱它。
不确定这是否足以解决您正在努力解决的具体问题,但我希望它有所帮助。
答案 1 :(得分:2)
正如adamarta所说,你的列表和列表之间存在1比1的映射关系。显示了什么。 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
等进行更改,但我认为这就是您所需要的。