2015-05-02 12 views
8

Nella mia app ho bisogno di mostrare le immagini all'interno di un ExpandableListView e deve essere una griglia di immagini, e queste immagini possono essere selezionabili in modo da avere un ListAdapter espandibile e al suo interno sono implementando un adattatore gridview, le immagini stanno andando bene come puoi vedere nell'immagine 1, ora quello che sto cercando di ottenere è l'immagine 2, come posso passare il groupPosition e il childPosition alla grigliaAdapter e quando clicco su l'immagine lo evidenzia? :GridView all'interno di ExpandableListView con scelta multipla su Android

enter image description here

Immagine 2: enter image description here

public class ExpandListAdapter extends BaseExpandableListAdapter { 


    public static final int CHOICE_MODE_MULTIPLE = AbsListView.CHOICE_MODE_MULTIPLE; 


    public static final int CHOICE_MODE_MULTIPLE_MODAL = AbsListView.CHOICE_MODE_MULTIPLE_MODAL; 

    /** 
    * No child could be selected 
    */ 
    public static final int CHOICE_MODE_NONE = AbsListView.CHOICE_MODE_NONE; 

    /** 
    * One single choice per group 
    */ 
    public static final int CHOICE_MODE_SINGLE_PER_GROUP = AbsListView.CHOICE_MODE_SINGLE; 

    /** 
    * One single choice for all the groups 
    */ 
    public static final int CHOICE_MODE_SINGLE_ABSOLUTE = 10001; 

    private Context context; 
    private ArrayList<Group> groups; 
    private ArrayList<ArrayList<Child>> child = new ArrayList(); 
    private ArrayList<Child> listchild; 
    private GridAdapter adapter; 
    private CustomGridView gridView; 
    private SparseArray<SparseBooleanArray> checkedPositions; 
    private static final String LOG_TAG = ExpandListAdapter.class.getSimpleName(); 

    private int choiceMode = CHOICE_MODE_MULTIPLE; 

    public ExpandListAdapter(Context context, ArrayList<Group> groups) { 
     this.context = context; 
     this.groups = groups; 
     checkedPositions = new SparseArray<SparseBooleanArray>(); 
     child = new ArrayList(); 
     for (int i = 0; i < groups.size(); i++) { 
      child.add(i, groups.get(i).getItems()); 
     } 
    } 

    public ExpandListAdapter(Context context, ArrayList<Group> children, int choiceMode) { 
     this(context, children); 
     // For now the choice mode CHOICE_MODE_MULTIPLE_MODAL 
     // is not implemented 
     if (choiceMode == CHOICE_MODE_MULTIPLE_MODAL) { 
      throw new RuntimeException("The choice mode CHOICE_MODE_MULTIPLE_MODAL " + 
        "has not implemented yet"); 
     } 
     this.choiceMode = choiceMode; 
    } 

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

    @Override 
    public long getChildId(int groupPosition, int childPosition) { 
     return childPosition; 
    } 

    @Override 
    public View getChildView(final int groupPosition, final int childPosition, 
          boolean isLastChild, View convertView, ViewGroup parent) { 


     if (convertView == null) { 
      LayoutInflater infalInflater = (LayoutInflater) context 
        .getSystemService(context.LAYOUT_INFLATER_SERVICE); 
      convertView = infalInflater.inflate(R.layout.gridview, null); 
     } 


     listchild = new ArrayList<Child>(); 

     for (int j = 0; j < groups.get(groupPosition).getItems().size(); j++) { 

      listchild.add(child.get(groupPosition).get(j)); 

     } 

     gridView = (CustomGridView) convertView.findViewById(R.id.GridView_toolbar); 

     gridView.setExpanded(true); 
     adapter = new GridAdapter(context, listchild, checkedPositions, groupPosition, childPosition); 
     gridView.setAdapter(adapter);// Adapter 
     gridView.setChoiceMode(CustomGridView.CHOICE_MODE_MULTIPLE); 
     gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 

      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 

       setClicked(groupPosition, childPosition); 
       System.out.println("position" + checkedPositions.get(groupPosition)); 
       if (checkedPositions.get(groupPosition) != null) { 
        boolean isChecked = checkedPositions.get(groupPosition).get(childPosition); 

        if(!isChecked){ 
        } 

       } else { 
        System.out.println("false"); 
       } 

      } 
     }); 


     return convertView; 

    } 

    public void setClicked(int groupPosition, int childPosition) { 
     switch (choiceMode) { 
      case CHOICE_MODE_MULTIPLE: 
       SparseBooleanArray checkedChildPositionsMultiple = checkedPositions.get(groupPosition); 
       // if in the group there was not any child checked 
       if (checkedChildPositionsMultiple == null) { 
        checkedChildPositionsMultiple = new SparseBooleanArray(); 
        // By default, the status of a child is not checked 
        // So a click will enable it 
        checkedChildPositionsMultiple.put(childPosition, true); 
        checkedPositions.put(groupPosition, checkedChildPositionsMultiple); 
       } else { 
        boolean oldState = checkedChildPositionsMultiple.get(childPosition); 
        checkedChildPositionsMultiple.put(childPosition, !oldState); 
       } 
       break; 
      // TODO: Implement it 
      case CHOICE_MODE_MULTIPLE_MODAL: 
       throw new RuntimeException("The choice mode CHOICE_MODE_MULTIPLE_MODAL " + 
         "has not implemented yet"); 
      case CHOICE_MODE_NONE: 
       checkedPositions.clear(); 
       break; 
      case CHOICE_MODE_SINGLE_PER_GROUP: 
       SparseBooleanArray checkedChildPositionsSingle = checkedPositions.get(groupPosition); 
       // If in the group there was not any child checked 
       if (checkedChildPositionsSingle == null) { 
        checkedChildPositionsSingle = new SparseBooleanArray(); 
        // By default, the status of a child is not checked 
        checkedChildPositionsSingle.put(childPosition, true); 
        checkedPositions.put(groupPosition, checkedChildPositionsSingle); 
       } else { 
        boolean oldState = checkedChildPositionsSingle.get(childPosition); 
        // If the old state was false, set it as the unique one which is true 
        if (!oldState) { 
         checkedChildPositionsSingle.clear(); 
         checkedChildPositionsSingle.put(childPosition, !oldState); 
        } // Else does not allow the user to uncheck it 
       } 
       break; 
      // This mode will remove all the checked positions from other groups 
      // and enable just one from the selected group 
      case CHOICE_MODE_SINGLE_ABSOLUTE: 
       checkedPositions.clear(); 
       SparseBooleanArray checkedChildPositionsSingleAbsolute = new SparseBooleanArray(); 
       checkedChildPositionsSingleAbsolute.put(childPosition, true); 
       checkedPositions.put(groupPosition, checkedChildPositionsSingleAbsolute); 
       break; 
     } 

     // Notify that some data has been changed 
     notifyDataSetChanged(); 
     Log.v(LOG_TAG, "List position updated"); 
     Log.v(LOG_TAG, PrintSparseArrays.sparseArrayToString(checkedPositions)); 
    } 

    public void setChoiceMode(int choiceMode) { 
     this.choiceMode = choiceMode; 
     // For now the choice mode CHOICE_MODEL_MULTIPLE_MODAL 
     // is not implemented 
     if (choiceMode == CHOICE_MODE_MULTIPLE_MODAL) { 
      throw new RuntimeException("The choice mode CHOICE_MODE_MULTIPLE_MODAL " + 
        "has not implemented yet"); 
     } 
     checkedPositions.clear(); 
     Log.v(LOG_TAG, "The choice mode has been changed. Now it is " + this.choiceMode); 
    } 

    @Override 
    public int getChildrenCount(int nGroup) { 
     return 1; 

    } 

    @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.group_item, null); 
     } 
     ExpandableListView mExpandableListView = (ExpandableListView) parent; 
     mExpandableListView.expandGroup(groupPosition); 
     TextView tv = (TextView) convertView.findViewById(R.id.group_name); 
     tv.setText(group.getName()); 

     return convertView; 
    } 

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

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

} 

GridAdapter:

public class GridAdapter extends BaseAdapter { 

    private Context mContext; 
    private ArrayList<Child> child; 
    ImageLoader imageLoader = AppController.getInstance().getImageLoader(); 
    private SparseArray<SparseBooleanArray> checkedPositions; 
    int groupPosition, childPosition; 

    public GridAdapter(Context context, ArrayList<Child> childValues, SparseArray<SparseBooleanArray> checkedPositions, int groupPosition, int childPosition) { 
     mContext = context; 
     child = childValues; 
     this.checkedPositions = checkedPositions; 
     this.childPosition = childPosition; 
     this.groupPosition = groupPosition; 
    } 


    @Override 
    public int getCount() { 
     return child.size(); 
    } 

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

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

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

     ViewHolder holder = null; 
     NetworkImageView i; 
     childPosition = position; 

     if (convertView == null) { 
      LayoutInflater inflater = (LayoutInflater) mContext 
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      convertView = inflater.inflate(R.layout.child_item, null); 
      holder = new ViewHolder(); 

      if (imageLoader == null) 
       imageLoader = AppController.getInstance().getImageLoader(); 

      i = (NetworkImageView) convertView 
        .findViewById(R.id.flag); 

      i.setImageUrl(String.valueOf(child.get(childPosition).getImage()), imageLoader); 


      convertView.setTag(holder); 

      System.out.println("position" + checkedPositions.get(groupPosition)); 
      if (checkedPositions.get(groupPosition) != null) { 
       boolean isChecked = checkedPositions.get(groupPosition).get(childPosition); 
       i.setBackgroundResource(R.color.bg); 

       if(!isChecked){ 
       } 

      } else { 
       System.out.println("false"); 
      } 


     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 
     holder.text = (TextView) convertView.findViewById(R.id.label); 
     holder.text.setText(child.get(position).getName()); 


     return convertView; 
    } 


    static class ViewHolder { 
     TextView text; 
    } 


} 
+0

Che tu possa aggiungere il layout e principale come bene? –

+1

hai bisogno di simili come questo: http://stackoverflow.com/q/21431097/1168654 –

risposta

1

In La mia ipotesi

ExpandListAdapter Classe

  • In getChildView() Metodo childPosition non dipende da ciò che bandiera del paese che viene cliccato, causa childPosition qui restituisce la posizione della vista Griglia, non le bandiere sotto di essa

  • Quindi, non c'è bisogno di passare childPosition nel costruttore di GridView, dal momento che childPosition restituirà sempre 1

  • per ottenere la bandiera reale cliccato posizione Usa onClickListener all'interno del vostro GridAdapter come:

@Override pubblica Vista GetView (int position, Vista convertView, ViewGroup genitore) {

 ViewHolder holder = null; 
     NetworkImageView i; 
     childPosition = position; 

     if (convertView == null) { 

     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 

     convertView.setOnclickListener(new OnClickListener{ 

      @Override 
      onClick(View v){ 
     isChecked=child.get(childPosition).isChecked(); 
     if(!isChecked){ 
      child.get(childPosition).setChecked(true); 
     } 
     else { 
      child.get(childPosition).setChecked(false); 
     }   

     }); 

Non c'è bisogno di gestire le posizioni controllato separatamente creare due metodi nella tua classe bambino isChecked () e setChecked() per mantenere deseleziona lo stato dei flag. Cambiare il colore della bandiera selezionato o controllato qui

 holder.text = (TextView) convertView.findViewById(R.id.label); 
     holder.text.setText(child.get(position).getName()); 


     return convertView; 
    } 

e rimuovere il Controllo logica da ExpandListAdapter Classe:

gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 

       @Override 
       public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 

        setClicked(groupPosition, childPosition); 
        System.out.println("position" + checkedPositions.get(groupPosition)); 
        if (checkedPositions.get(groupPosition) != null) { 
         boolean isChecked = checkedPositions.get(groupPosition).get(childPosition); 

         if(!isChecked){ 
         } 

        } else { 
         System.out.println("false"); 
        } 

       } 
      }); 
+1

puoi modificare il tuo codice, sto ricevendo nullpointerexception su isChecked = checkedPositions.get (groupPosition) .get (childPosition); – AND4011002849

+0

è meglio mantenere una bandiera booleana deselezionata nella tua classe ** Child **. isChecked() return boolean Riduce il carico di lavoro e non è necessario mantenere un array sparse *** ** separato di posizioni controllate. Quindi il codice può essere: // per il flag di richiamo isChecked = child.get (childPosition) .IsChecked(); // per l'impostazione del flag child.get (childPosition) .setChecked (true); Sto modificando il codice di conseguenza –

+0

Ho aggiunto un metodo nella classe di mio figlio in questo modo: public booleano isChecked() { return false; } ma quello restituirà sempre falso, è quello corretto? Non riesco a vedere come agisce quando faccio clic sulla bandiera – AND4011002849

0

è necessario impostare un 'OnItemClickListener' al vostro gridAdapter e overide il metodo onItemClick come segue.

Nota: - Questo evidenzierà la Vista immagine che si fa clic e se è successo a fare clic su un altro ImageView nella stessa GridView, anche ImageView verrà evidenziato! Come in una "selezione multipla".

gridAdapter.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
      ImageView selectedFlagImageView = (ImageView) view; 
      selectedFlagImageView.setBackgroundColor(Color.parseColor("#37a93400")); 
     } 
    }); 

Ciò colorare lo sfondo della ImageView selezionato.Codice del colore che ho usato in qui è semplicemente, più alfa e meno RGBs. (io ho usato Android Studio Color Chooser)

android studio color chooser

seguenti immagini vi darà un'idea di come apparirà nel pronunciarsi su un fondo colore come questo

Senza colore di sfondo:

image view with no background colors

Con il colore di sfondo:

image view with background color

+0

Nessun listener può essere aggiunto agli adattatori –

Problemi correlati