I am having a problem with the expandablelistview. All the tutorials I've seen regarding the parent item have only one item. In my case I'm doing with multiple fields (name and comment) in both parent and child. How should I proceed?
my json data
[
{
nome: "Carlos",
comentario: "Esse dia foi show",
resp: [ ]
},
{
nome: "Andre",
comentario: "Acho que não precisava disso",
resp: [
{
nome: "inutil",
comentario: "Sempre assim"
},
{
nome: "Roberto",
comentario: "Se não estivessem fazendo nada errado, não iam querer apagar a mídia."
},
{
nome: "xumbinho",
comentario: "André ! Para vai!"
}
]
},
{
nome: "Celso",
comentario: "É pra acabar mesmo",
resp: [ ]
}
]
And my ComentariosActivity code
private void makejsonobjreq() {
PD.show();
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Method.GET, url+"284901",
null, response -> {
ArrayList<Group> list = new ArrayList<Group>();
ArrayList<Child> ch_list;
Log.d("response", String.valueOf(response));
try {
Iterator<String> key = response.keys();
while (key.hasNext()) {
String k = key.next();
Log.d("KEY", String.valueOf(k));
Group gru = new Group();
gru.setNome(k);
ch_list = new ArrayList<Child>();
JSONArray ja = response.getJSONArray(k);
Log.d("QNT", String.valueOf(ja.length()));
for (int i = 0; i < ja.length(); i++) {
JSONObject jo = ja.getJSONObject(i);
Child ch = new Child();
Log.d("COMENTARIO NOME",jo.getString("nome"));
ch.setNome(jo.getString("nome"));
ch.setComentario(jo.getString("comentario"));
ch_list.add(ch);
} // for loop end
gru.setItems(ch_list);
list.add(gru);
} // while loop end
ExpAdapter = new ExpandListAdapter(ComentariosActivity.this, list);
ExpandList.setAdapter(ExpAdapter);
PD.dismiss();
} catch (JSONException e) {
e.printStackTrace();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
PD.dismiss();
Log.d("response", String.valueOf(error));
}
});
MyApplication.getInstance().addToRequestQueue(jsonObjReq, "jreq");
}
Adapter
package br.inf.cgn.cgnapp;
import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;
import com.android.volley.toolbox.ImageLoader;
import br.inf.cgn.cgnapp.model.Child;
import br.inf.cgn.cgnapp.model.Group;
public class ExpandListAdapter extends BaseExpandableListAdapter {
private Context context;
private ArrayList<Group> groups;
ImageLoader imageLoader = MyApplication.getInstance().getImageLoader();
public ExpandListAdapter(Context context, ArrayList<Group> groups) {
this.context = context;
this.groups = groups;
}
@Override
public Object getChild(int groupPosition, int childPosition) {
ArrayList<Child> chList = groups.get(groupPosition).getItems();
return chList.get(childPosition);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
Child child = (Child) getChild(groupPosition, childPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) context
.getSystemService(context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.comentarios_resp, null);
}
if (imageLoader == null)
imageLoader = MyApplication.getInstance().getImageLoader();
TextView nome = (TextView) convertView.findViewById(R.id.nome_resp);
nome.setText(child.getNome().toString());
TextView comentario = (TextView) convertView.findViewById(R.id.comentario_resp);
comentario.setText(child.getComentario().toString());
return convertView;
}
@Override
public int getChildrenCount(int groupPosition) {
ArrayList<Child> chList = groups.get(groupPosition).getItems();
return chList.size();
}
@Override
public Object getGroup(int groupPosition) {
return groups.get(groupPosition);
}
@Override
public int getGroupCount() {
return groups.size();
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
Group group = (Group) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater inf = (LayoutInflater) context
.getSystemService(context.LAYOUT_INFLATER_SERVICE);
convertView = inf.inflate(R.layout.comentarios_list, null);
}
TextView nome = (TextView) convertView.findViewById(R.id.nome);
nome.setText(group.getNome());
TextView comentario = (TextView) convertView.findViewById(R.id.comentario);
comentario.setText(group.getComentario());
return convertView;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
I tried several ways to make this code work but with no success!
I've added code that will parse the JSON response and populate the data for the adapter. It is a complete example. But it needs an XML file with an ExpandableListView named "list".
I borrowed a basic adapter from another stackoverflow post. It only displays basic text, not the entire conversation. But it is probably enough code to get you unblocked. But you'll need to replace the simple views like: android.R.layout.simple_list_item_1 with your own views.
In the real app, it is probably best to parse the JSON data in an ASyncTask.
package com.example.elletlar.myapplication;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List<Group> list = getList();
ExpAdapter adapter = new ExpAdapter(this, list);
ExpandableListView listView = findViewById(R.id.lst);
listView.setAdapter(adapter);
}
public class Group {
String name;
private List<Child> childList;
void setChildList(List<Child> list) {
childList = list;
}
List<Child> getChildList() {
return childList;
}
}
public class Child {
String name;
String comment;
}
private ArrayList<Group> getList() {
ArrayList<Group> list = new ArrayList<>();
JSONArray groupArr;
try {
String TEST = "[" +
"{" +
"nome: \"Carlos\"," +
" comentario: \"Esse dia foi show\"," +
" resp: [ ]" +
" }," +
" {" +
" nome: \"Andre\"," +
" comentario: \"Acho que não precisava disso\"," +
" resp: [" +
" {" +
" nome: \"inutil\"," +
" comentario: \"Sempre assim\"" +
" }," +
" {" +
" nome: \"Roberto\"," +
" comentario: \"Se não estivessem fazendo nada errado, não iam querer apagar a mídia.\"\n" +
" }," +
" {" +
" nome: \"xumbinho\"," +
" comentario: \"André ! Para vai!\"" +
" }" +
" ]" +
" }" +
"]";
groupArr = new JSONArray(TEST);
ArrayList<Child> childList;
for (int i = 0; i < groupArr.length(); ++i) {
JSONObject groupObj= groupArr.getJSONObject(i);
Group group = new Group();
group.name = groupObj.getString("nome");
childList = new ArrayList<>();
JSONArray replyArr = groupObj.getJSONArray("resp");
for (int j = 0; j < replyArr.length(); ++j) {
JSONObject childObj = replyArr.getJSONObject(j);
Child child = new Child();
child.name = (childObj.getString("nome"));
child.comment = (childObj.getString("comentario"));
childList.add(child);
} // for loop end
group.setChildList(childList);
list.add(group);
}
} catch (JSONException e) {
e.printStackTrace();
}
return list;
}
public class ExpAdapter extends BaseExpandableListAdapter {
private final class ViewHolder {
TextView textLabel;
}
private final List<Group> itemList;
private final LayoutInflater inflater;
private ExpAdapter(Context context, List<Group> itemList) {
this.inflater = LayoutInflater.from(context);
this.itemList = itemList;
}
@Override
public Child getChild(int groupPosition, int childPosition) {
return itemList.get(groupPosition).getChildList().get(childPosition);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public int getChildrenCount(int groupPosition) {
return itemList.get(groupPosition).getChildList().size();
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
final ViewGroup parent) {
View resultView = convertView;
ViewHolder holder;
if (resultView == null) {
resultView = inflater.inflate(android.R.layout.simple_list_item_1, null); //TODO change layout id
holder = new ViewHolder();
holder.textLabel = resultView.findViewById(android.R.id.text1); //TODO change view id
resultView.setTag(holder);
} else {
holder = (ViewHolder) resultView.getTag();
}
final Child item = getChild(groupPosition, childPosition);
holder.textLabel.setText(item.name);
return resultView;
}
@Override
public Group getGroup(int groupPosition) {
return itemList.get(groupPosition);
}
@Override
public int getGroupCount() {
return itemList.size();
}
@Override
public long getGroupId(final int groupPosition) {
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View theConvertView, ViewGroup parent) {
View resultView = theConvertView;
ViewHolder holder;
if (resultView == null) {
resultView = inflater.inflate(android.R.layout.simple_list_item_1, null);
holder = new ViewHolder();
holder.textLabel = resultView.findViewById(android.R.id.text1);
resultView.setTag(holder);
} else {
holder = (ViewHolder) resultView.getTag();
}
final Group item = getGroup(groupPosition);
holder.textLabel.setText(item.name);
return resultView;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
}
Here are some samples of making HTTP requests: Using URLConnection
Also, you might look at using the Volley framework: Volley
Simple and very popular framework for HTTP requests: OK HTTP
For Kotlin, I use Fuel: Fuel
Beware, most of the answers on Stackoverflow about downloading items use a class called: DefaultHttpClient that is from the Apache library. Google decided to remove the Apache libraries a couple of Android versions ago. It is still possible to use them by tweaking the Gradle file, but that's only for legacy apps. New apps should use classes like: URLConnection. Converting Apache to Current Android HTTP Classes