2016-05-24 12 views
0

Ich habe diese Übung viel zu lange festgefahren.Erstellen eines benutzerdefinierten ArrayAdapter und Füllen einer ListView mit einem angeforderten Json mit Volley

Ich habe einen Teil des Codes gegeben und ich musste den Rest davon schreiben.

Zuerst bekam ich eine VolleyManager-Klasse, die mit einigen Volley-Werkzeugen hilft (wie Hinzufügen zur Anforderungswarteschlange). Dann eine andere Gson-Klasse, die beim Parsen des angeforderten JSON hilft.

Dies ist der Code für die UserListFragment, wo zwei Schaltflächen vorhanden sind. Eine zum Auffüllen der Liste, eine zum Löschen der Liste und die Liste selbst unter diesen beiden Schaltflächen.

public class UserListFragment extends Fragment { 

private static final String USERS_URL = "https://raw.githubusercontent.com/bengui/volleytest/master/json/users.json"; 
private static final String TAG = UserListFragment.class.getSimpleName(); 

private View view; 
private ListAdapter listAdapter; 
private Button requestButton; 
private Button cleanButton; 
private ListView listView; 

@Nullable 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    view = inflater.inflate(R.layout.fragment_user_list, null); 

    // UI Elements 
    requestButton = (Button) view.findViewById(R.id.request_btn); 
    listView = (ListView) view.findViewById(R.id.listview_users); 
    requestButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      listAdapter = new ListAdapter(view.getContext()); 
      listView.setAdapter(listAdapter); 
     } 
    }); 

    cleanButton = (Button) view.findViewById(R.id.clean_btn); 
    cleanButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      listView.setAdapter(null); 
     } 
    }); 
    return view; 
} 

Dies ist der personalisierte Adapter, den ich gemacht habe, um die Elemente auf der Liste zu füllen.

public class ListAdapter extends ArrayAdapter { 

     VolleyManager volleyManager; 
     List<User> list; 

     public ListAdapter(Context context){ 
      super(context,0); 
      volleyManager = VolleyManager.getInstance(getActivity()); 

      requestButton.setEnabled(false); 

      JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(
        USERS_URL, 
        new Response.Listener<JSONArray>() { 
         @Override 
         public void onResponse(JSONArray response) { 
          list = parseUserList(response.toString()); 
          requestButton.setEnabled(true); 
          notifyDataSetChanged(); 
         } 
        }, 
        new Response.ErrorListener() { 
         @Override 
         public void onErrorResponse(VolleyError error){ 
          Log.d(TAG, "JSON response error : " + error.getMessage()); 
          requestButton.setEnabled(true); 
         } 
        } 
      ); 
      volleyManager.addToRequestQueue(jsonArrayRequest); 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
      LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext()); 

      View listItemView = convertView; 

      if (null == convertView) { 
       listItemView = layoutInflater.inflate(
         R.layout.fragment_list_item, 
         parent, 
         false); 
      } 

      // Pick an element of the list and fill the UI textViews. 
      User user = list.get(position); 

      TextView nombre = (TextView) listItemView.findViewById(R.id.user_name); 
      TextView apellido = (TextView) listItemView.findViewById(R.id.user_last_name); 
      TextView edad = (TextView) listItemView.findViewById(R.id.user_age); 

      // Update views 
      nombre.setText(user.getName()); 
      apellido.setText(user.getLastName()); 
      edad.setText(user.getAge()); 

      return listItemView; 
     } 
    } 

    /** 
    * Parses a users json array into a users list. 
    * 
    * @param jsonArray 
    * 
    * @return Users list 
    */ 
    private List<User> parseUserList(String jsonArray) { 
     Gson gson = new Gson(); 

     // Declares the list type 
     Type listType = new TypeToken<List<User>>() {}.getType(); 

     List<User> userList = gson.fromJson(jsonArray, listType); 

     return userList; 
    } 
} 

Ich bin mir nicht sicher, warum das nicht funktioniert. Vielleicht verstehe ich nicht vollständig, wie Adapter funktionieren, und ich mache einen falschen Anruf auf dem Button Click Listener?

Ich habe versucht, dies für über eine Woche herauszufinden. Etwas Fortschritt gemacht! aber immer noch kann es nicht funktionieren.

Jede Eingabe ist willkommen.

bearbeiten: Vergessen Sie die .xmls

Dies ist das Layout für das Fragment.

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/fragment_user_list" 
android:orientation="vertical" 
android:layout_width="match_parent" 
android:layout_height="match_parent"> 

<Button 
    android:id="@+id/request_btn" 
    android:text="@string/request_btn" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"/> 

<Button 
    android:id="@+id/clean_btn" 
    android:text="@string/clean_btn" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"/> 

<ListView 
    android:id="@+id/listview_users" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"/> 

</LinearLayout> 

Dies ist das Layout für die Listview-Elemente.

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="horizontal" 
android:layout_width="match_parent" 
android:layout_height="match_parent"> 

<TextView 
    android:id="@+id/user_name" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"/> 

<TextView 
    android:id="@+id/user_last_name" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"/> 

<TextView 
    android:id="@+id/user_age" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"/> 

</LinearLayout> 
+0

Was genau ist das Problem? Zeigt es nicht die Liste? – Dave

+0

Ja, zeigt nichts auf dem Display an. Die Daten werden jedoch abgerufen. –

+0

Haben Sie überprüft, dass getView aufgerufen wird, nachdem Ihre Listenvariable ausgefüllt wurde? – Dave

Antwort

0

Try recycler_View zu verwenden ... Recycler_View viele Dinge verwalten können Sie brauchen, um über sie keine Sorge ...

+0

RecyclerView ist ein Thema, das ich studieren muss ... Ich dachte, es war etwas, das die Leistung nur durch weniger Listenelemente verbessert? –

+0

Versuchen Sie dies in Ihrer onCreate() Methode ... ListAdapter customAdapter = new ListAdapter (this, R.layout.list_item, tempList); – Zombie

+0

Ich denke, dass diese Zeile ist, wenn jedes Listenelement nur eine Textansicht hat. In diesem Fall hat jedes Element auf der Liste 3 textViews, deshalb musste ich einen benutzerdefinierten Adapter erstellen. –

0

Um eine Json in einem Listview Sie die folgenden Schritte zu analysieren: 1- erstellen sie eine Klasse werden die Daten aus dem jSON-Objekt wie folgt halten:

public class Person { 

    String name; 
    String last_name; 
    String age; 

    public Person() { 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getLast_name() { 
     return last_name; 
    } 

    public void setLast_name(String last_name) { 
     this.last_name = last_name; 
    } 

    public String getAge() { 
     return age; 
    } 

    public void setAge(String age) { 
     this.age = age; 
    } 
} 

2- erstellen einer Klasse und nennen sie es Adapter setzen es in Listenansicht wie folgt aus:

import android.app.Activity; 
import android.content.Context; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.BaseAdapter; 
import android.widget.TextView; 
import java.util.List; 
public class Adapter extends BaseAdapter{ 

    private LayoutInflater inflater; 
    private Activity activity; 
    private List<Person> persons; 
    private TextView userName ; 
    private TextView lastName; 
    private TextView age ; 

    public Adapter(Activity activity, List<Person> items){ 
     this.activity=activity; 
     this.persons=items; 
    } 
    @Override 
    public int getCount() { 
     return persons.size(); 
    } 

    @Override 
    public Object getItem(int position) { 
     return persons.get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 



      if(inflater==null){ 
       inflater=(LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      } 
      if(convertView ==null){ 
       convertView=inflater.inflate(R.layout.custom_layout,null); 

      } 

     userName=(TextView)convertView.findViewById(R.id.user_name); 
     lastName=(TextView)convertView.findViewById(R.id.last_name); 
     age=(TextView)convertView.findViewById(R.id.age); 

     Person person=persons.get(position); 

     userName.setText("Name:"+person.getName()); 
     lastName.setText("LastName:"+person.getLast_name()); 
     age.setText("Age"+person.getAge()); 

     return convertView; 
    } 
} 

3- Im Inneren des Fragments, das Sie die Listenansicht Elemente auffüllen möchten (ich den gleichen Link für json in diesem Fragment verwendet und es funktioniert erfolgreich):

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ListView; 
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.JsonArrayRequest; 
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; 

public class PersonFragment extends Fragment { 

    private static final String JSON_URL = "https://raw.githubusercontent.com/bengui/volleytest/master/json/users.json"; 
    public static List<Person> personList = new ArrayList<>(); 
    private ListView listView; 
    public static Adapter adapter; 

    public PersonFragment() { 
     // Required empty public constructor 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View view=inflater.inflate(R.layout.your_fragment_layout, container, false); 
     listView = (ListView)view.findViewById(R.id.persons_listView); 
     adapter=new Adapter(getActivity(),personList); 
     listView.setAdapter(adapter); 
     setListViewData(); 

     return view; 
    } 

    private void setListViewData() { 


     RequestQueue requestQueue = Volley.newRequestQueue(getContext()); 
     JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, JSON_URL, new Response.Listener<JSONArray>() { 
      public void onResponse(JSONArray jsonArray) { 
       if (jsonArray.length() > 0) { 

        for (int i = 0; i < jsonArray.length(); i++) { 
         try { 

          JSONObject obj = jsonArray.getJSONObject(i); 
          Person person =new Person(); 
          person.setName(obj.getString("name")); 
          person.setLast_name(obj.getString("last_name")); 
          person.setAge(obj.getString("age")); 

          personList.add(person); 

         } catch (JSONException e) { 
          e.printStackTrace(); 
         } 
         adapter.notifyDataSetChanged(); 
        } 
       } 

      } 
      // setArrayListLength(titles); 
      // Toast.makeText(getApplicationContext(),""+titles.size(),Toast.LENGTH_SHORT 
      //).show(); 

     }, new Response.ErrorListener() { 
      @Override 
      public void onErrorResponse(VolleyError volleyError) { 
       Log.e("Error", "Unable to parse json array2"); 
      } 
     }); 
     // add json array request to the request queue 
     requestQueue.add(jsonArrayRequest); 


    } 
} 

4- innen Layout-Ordner custom_layout erstellen. xml wie folgt aus:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 

xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical" > 
     <TextView 
      android:id="@+id/user_name" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="userName" 
      android:textSize="20dp"/> 

     <TextView 
      android:id="@+id/last_name" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="userName" 
      android:textSize="20dp" 
      android:paddingTop="10dp" 

      /> 

    <TextView 

     android:id="@+id/age" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="userName" 
     android:paddingTop="10dp" 
     /> 

</LinearLayout> 

5- eine andere xML-Ressource innerhalb des Layout-Ordner erstellen und benennen sie es your_fragment_layout.xml wie folgt aus:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 

    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    > 


    <ListView 
     android:id="@+id/persons_listView" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:dividerHeight="5dp" 
     ></ListView> 


</RelativeLayout> 

Schließlich vergessen diese Abhängigkeit nicht, sie in Ihr Projekt gradle

compile 'com.mcxiaoke.volley:library:1.0.17' 

auch nicht hinzufügen Vergessen Sie das Internet Genehmigung Ihre Manifest-Datei wie folgt hinzufügen:

<uses-permission android:name="android.permission.INTERNET" /> 

Ich habe dieses Fragment getestet und es funktioniert erfolgreich. Hoffe das hat dir geholfen.

+0

Hey vielen Dank für alles. Wenn ich kopiert, funktioniert es. Ich musste nur einen Parameter aus der JSON-Anfrage entfernen (der Parameter Request.Method.GET wird nicht benötigt, da er automatisch von seinem eigenen Konstruktor aufgerufen wird, obwohl ich denke, dass die Codezeile, die Sie mir gegeben haben, trotzdem funktionieren sollte). Noch werde ich versuchen, es von einem Knopf zu arbeiten, jetzt, dass ich etwas Arbeitscode habe! Danke nochmal Mann! –

+0

Sie können meine Antwort als richtige Antwort wählen! –