2016-05-17 16 views
1

Ich habe eine ExpandableListAdapter implementiert, und es funktioniert offenbar gut. Nur wenn die Aktivität fortgesetzt wird, werden die untergeordneten Knoten wiederholt. Ich weiß nicht, wie ich das beheben kann, ich habe online danach gesucht und nichts hilfreiches gefunden.ExpandableListView wiederholte Kindknoten

Ich habe das Problem abgeschwächt und einige != null Prüfungen hinzugefügt. So vermeiden Sie das Einfügen und Erstellen neuer Daten, wenn sie nicht benötigt werden. Aber das hat das Problem nicht behoben.

Hier ist der CustomAdapter

public class ContatoAdapter extends BaseExpandableListAdapter { 

private final Activity context; 
private final Map<String, List<Contato>> contatosCollection; 
private final List<String> area; 

public ContatoAdapter(Activity context, List<String> area, Map<String, List<Contato>> contatosCollection) { 
    this.context = context; 
    this.contatosCollection = contatosCollection; 
    this.area = area; 
} 

@Override 
public int getGroupCount() { 
    return area.size() ; 
} 

@Override 
public int getChildrenCount(int groupPosition) { 
    return this.contatosCollection.get(area.get(groupPosition)).size(); 
} 


@Override 
public Object getGroup(int groupPosition) { 
    return this.area.get(groupPosition); 
} 

@Override 
public Object getChild(int groupPosition, int childPosition) { 
    return this.contatosCollection.get(this.area.get(groupPosition)).get(childPosition); 
} 

@Override 
public long getGroupId(int groupPosition) { 
    return this.area.get(groupPosition).hashCode(); 
} 

@Override 
public long getChildId(int groupPosition, int childPosition) { 
    return this.contatosCollection.get(this.area.get(groupPosition)).get(childPosition).hashCode(); 
} 

@Override 
public boolean hasStableIds() { 
    return false; 
} 

@Override 
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { 
    String s = (String) getGroup(groupPosition); 
    final LayoutInflater gInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    if (convertView == null){ 
     convertView = gInflater.inflate(R.layout.group_item, parent, false); 
    } 

    final TextView item = (TextView) convertView.findViewById(R.id.list_header); 

    item.setText(s); 
    item.setTypeface(null, Typeface.BOLD); 

    return convertView; 
} 

@Override 
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { 
    final Contato contato = (Contato) getChild(groupPosition, childPosition); 
    final LayoutInflater cInflater = this.context.getLayoutInflater(); 

    if (convertView == null){ 
     convertView = cInflater.inflate(R.layout.list_item, parent, false); 
    } 

    TextView item = (TextView) convertView.findViewById(R.id.list_item_nome); 
    ImageView ver = (ImageView) convertView.findViewById(R.id.list_item_ver); 

    ver.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Intent intent = new Intent(context.getApplicationContext(), DetalheActivity.class); 
      intent.putExtra("contato", contato); 
      context.startActivity(intent); 
     } 
    }); 

    item.setText(contato.getNome()); 

    return convertView; 
} 

@Override 
public boolean isChildSelectable(int groupPosition, int childPosition) { 
    return true; 
} 
} 

Hier ist die Aktivität, die die listView mit dem Adapter hat:

public class MedicosActivity extends AppCompatActivity { 
private ExpandableListView listView; 
private ArrayList<Contato> contatos; 
private ArrayList<String> areas; 
private HashMap<String, List<Contato>> contatosCollection; 
private ContatoAdapter adapter; 

String jsonString = ""; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_medicos); 

    setTitle("Médicos | Etc"); 

    init(); 

    if (listView == null) 
     listView = (ExpandableListView) findViewById(android.R.id.list); 
    adapter = new ContatoAdapter(this,areas,contatosCollection); 
    listView.setAdapter(adapter); 

    listView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() { 
     @Override 
     public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { 
      Contato selected = (Contato) adapter.getChild(groupPosition,childPosition); 
      Toast.makeText(MedicosActivity.this, selected.getNome() , Toast.LENGTH_SHORT).show(); 

      return true; 
     } 
    }); 
} 

private void init() { 
    if (jsonString.isEmpty()) 
     jsonString = JsonUtil.loadJSON(MedicosActivity.this, "data.json"); 
    if (contatosCollection == null) 
     contatos = JsonUtil.parseJSON(jsonString); 
    if (areas == null){ 
     areas = new ArrayList<>(); 
     createGroupList(); 
    } 
    if (contatosCollection == null){ 
     contatosCollection = new HashMap<>(); 
     createCollection(); 
    } 
} 

private void createGroupList() { 
    for(Contato c : contatos){ 
     if (!areas.contains(c.getArea())){ 
      areas.add(c.getArea()); 
     } 
    } 
} 

private void createCollection() { 
    for (Contato c : contatos){ 
     List<Contato> ctg = contatosCollection.get(c.getArea()); 
     if (ctg == null){ 
      ctg = new ArrayList<>(); 
      contatosCollection.put(c.getArea(), ctg); 
     } 
     ctg.add(c); 
    } 
} 
} 

die JSON Parser Klasse hinzufügen, die den Fehler verursacht:

private static ArrayList<Contato> contatoList = new ArrayList<>(); 
public static ArrayList<Contato> parseJSON(String jsonString){ 
    try { 
     JSONObject jsonObject = new JSONObject(jsonString); 
     JSONArray jsonArray = jsonObject.optJSONArray("medicos"); 

     for (int i = 0; i < jsonArray.length(); i++){ 
      JSONObject medicoObj = jsonArray.getJSONObject(i); 
      JSONObject end = medicoObj.getJSONObject("endereco"); 
       JSONArray coord = end.getJSONArray("coord"); 
       LatLng latLng = new LatLng(coord.getDouble(0), coord.getDouble(1)); 
       JSONArray telefones = medicoObj.getJSONArray("telefone"); 
       String[] tels = new String[telefones.length()]; 
       for (int j = 0; i < telefones.length(); i++) { 
        tels[i] = telefones.get(i).toString(); 
       } 
       Contato c = new Contato(
         medicoObj.getString("area") 
         , medicoObj.getString("nome") 
         , end.getString("rua") 
         , Integer.parseInt(end.getString("numero")) 
         , end.getString("complemento") 
         , tels 
         , latLng 
       ); 
       contatoList.add(c); 
     } 

     return contatoList; 
    } catch (JSONException e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 
+0

Sind Sie sicher, dass die Daten an den Adapter weitergegeben nicht dupliziert Werte haben? –

+0

JA .. danke, du hast mich dazu gebracht, genau das zu debuggen. Ich möchte verrückt gehen und denken, dass das Problem mein Adapter war und nicht in die Array-Werte schaute. Tatsächlich war das Problem die ArrayList , die beim Abrufen von Daten von JSON dupliziert wurde. Ich habe meinen Parser-Code geändert, um Duplikate zu prüfen, und es funktioniert einwandfrei. Wird eine Antwort posten. –

Antwort

1

Dank zu Flüssiger Pinguin Kommentar Ich konnte das Problem erkennen. Da ich in der Adapter Klasse nach Problemen suchte, bemerkte ich nicht die wiederholten Daten, die von der JSON parser Klasse kamen.

Es wurde nicht nach doppelten Daten gesucht, wenn Daten vom JSON zum Array abgerufen werden. Hier kommt der feste Parser code mit den erforderlichen Überprüfungen:

private static ArrayList<Contato> contatoList = new ArrayList<>(); 
public static ArrayList<Contato> parseJSON(String jsonString){ 
    try { 
     JSONObject jsonObject = new JSONObject(jsonString); 

     JSONArray jsonArray = jsonObject.optJSONArray("medicos"); 

      for (int i = 0; i < jsonArray.length(); i++) { 
       JSONObject medicoObj = jsonArray.getJSONObject(i); 
       if (medicoObj.length() != contatoList.size()) { 
        JSONObject end = medicoObj.getJSONObject("endereco"); 
        JSONArray coord = end.getJSONArray("coord"); 
        LatLng latLng = new LatLng(coord.getDouble(0), coord.getDouble(1)); 
        JSONArray telefones = medicoObj.getJSONArray("telefone"); 
        String[] tels = new String[telefones.length()]; 
        for (int j = 0; i < telefones.length(); i++) { 
         tels[i] = telefones.get(i).toString(); 
        } 
        Contato c = new Contato(
          medicoObj.getString("area") 
          , medicoObj.getString("nome") 
          , end.getString("rua") 
          , Integer.parseInt(end.getString("numero")) 
          , end.getString("complemento") 
          , tels 
          , latLng 
        ); 
        if (!contatoList.contains(c)) 
         contatoList.add(c); 
       } 
      } 

     return contatoList; 
    } catch (JSONException e) { 
     e.printStackTrace(); 
    } 
    return null; 
}