2016-05-17 58 views
1

我實現了ExpandableListAdapter,它顯然工作得很好。除了活動恢復時,子節點重複。我不知道如何解決這個問題,我在網上搜索這個,沒有發現任何有用的信息。ExpandableListView重複子節點

我減輕了問題,增加了一些!= null檢查。從而避免在不需要時插入和創建新數據。但是這並沒有解決問題。

這裏的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; 
} 
} 

下面是有listView與適配器的活動:

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); 
    } 
} 
} 

增加導致錯誤的JSON解析類:

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

您確定傳遞給適配器的數據沒有重複的值嗎? –

+0

是的..謝謝你,你讓我調試只是。我想瘋了,認爲問題是我的適配器,並沒有看着數組值。其實問題是ArrayList 從JSON獲取數據時得到了重複。更改我的解析器代碼來檢查重複項,並且工作正常。將發佈答案。 –

回答

1

謝謝到液體企鵝評論我能夠發現問題。由於我正在研究Adapter班的問題,因此我不知道來自JSON parser班的重複數據。

當從JSON獲取數據到數組時,它不檢查重複數據。這裏是需要驗證的固定解析器code

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; 
}