2017-07-29 29 views
1

我的目標是從適配器中提取三個JSON Objects,並將它們顯示爲一個list item中的三個文本視圖。它應該是這樣的,當只有一個本組對象: enter image description here單個列表項中未正確包含的視圖

相反,它顯示的:

enter image description here

我看不出什麼錯在我的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

嘗試'HashMap '。它會給你關鍵的價值對。 –

回答

2

我的目標是從適配器中提取3個JSON對象,並在一個列表項中顯示它們作爲3個文本視圖。當目前只有一組對象時,它應該看起來像這樣:

列表適配器設計爲具有支持它的列表的1對1映射。因此,根據我的理解,您的方法有點有缺陷。如果要將三個JSON對象顯示爲單一列表項目的三個TextView,則需要轉換爲另一個列表(例如),該列表由您定義的類別ViewHolder組成。使用自定義適配器查找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中沒有方向屬性,所以你也需要去掉它。

不知道這是否足以解決您遇到的具體問題,但我希望它有幫助。

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. 

至於你的佈局,如果它看起來OK預覽,那麼它可能是好的。除了...... 您正在使用這些值替換標籤(Room &時間)。我不認爲你想這樣做。我認爲這是你需要的。

<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等變化,但我覺得這是你所需要的。

+0

謝謝。這很好地脫離了阿達瑪拉的答案。你們都提供了關於如何正確構建這些問題的驚人背景。在你的幫助下,我能夠使它工作。我還會發布更新,詳細介紹我爲實現它所做的更改。 – hackerman

+0

很高興有幫助 – Gary99

相關問題