java - sale - Intentando anular la selección de una vista usando getChildAt()
nullpointerexception processing (2)
Estoy usando un GridView
dentro de una ExpandableListView
Tengo una función que resalta un elemento cuando se hace clic en él, ahora estoy tratando de implementar un botón que, al presionarlo, deseleccionará todos los elementos seleccionados, pero está deseleccionando solo la última vista en la que se hizo clic
public class GridAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<Filhos> child;
public ArrayList<CadastraEscolas> escola;
private ArrayList<ArrayList<Filhos>> filhos = new ArrayList();
public GridAdapter(Context context, ArrayList<CadastraEscolas> groups, ArrayList<Filhos> childValues, int groupPosition) {
mContext = context;
child = childValues;
escola = groups;
posicaoEscola = 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(final int position, View convertView, final ViewGroup parent) {
holder = null;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.child_item, null);
holder = new ViewHolder();
final TextView idAluno = (TextView) convertView.findViewById(R.id.idcrianca);
final TextView nomeAluno = (TextView) convertView.findViewById(R.id.name);
convertView.setTag(holder);
final View finalConvertView = convertView;
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (list.size() > 0) {
isChecked = filhos.get(posicaoEscola).get(position).isChecked();
if (!isChecked) {
selecao(true, position, nomeAluno, 0xFFFFFFFF, finalConvertView, View.VISIBLE);
} else {
selecao(false, position, nomeAluno, 0xFFD5672B, finalConvertView, View.GONE);
}
ex.findViewById(R.id.notificar).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
limpaSelecao(false, position, nomeAluno, 0xFFD5672B, parent, View.GONE);
}
});
}
});
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.text.setText(child.get(position).getNome());
return convertView;
}
static class ViewHolder {
TextView text;
}
public void selecao(boolean check, int position, TextView nomeAluno, int color, View v, int visibility) {
filhos.get(posicaoEscola).get(position).setChecked(check);
nomeAluno.setTextColor(color);
v.findViewById(R.id.overlay).setVisibility(visibility);
v.findViewById(R.id.overlayText).setVisibility(visibility);
}
public void limpaSelecao(boolean check, int position, TextView nomeAluno, int color, ViewGroup v, int visibility) {
for (int x = 0; x < group.size(); x++) {
for (int j = 0; j < group.get(x).getalunos().size(); j++) {
if(filhos.get(x).get(j).isChecked()){
v.getChildAt(j).findViewById(R.id.loadingPanel).findViewById(R.id.overlay).setVisibility(View.GONE);
}
nomeAluno.setTextColor(color);
}
}
}
}
Diseño:
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/nomealuno_main"
android:layout_below="@+id/child">
<View
android:id="@+id/overlay"
android:layout_width="125dp"
android:layout_height="50dp"
android:background="@color/bgOverlay"
android:visibility="gone"/>
</RelativeLayout>
Esto es lo que está pasando:
cuando selecciono todos los elementos de A a B de esa manera:
Y acierta, solo eliminará los niños seleccionados del último grupo en el que hice clic:
Necesito eliminarlos todos cuando hago clic en Borrar, todos los niños sin importar en qué grupo tienen que ser eliminados.
Expansible Adaptador:
public class ExpandListTest 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;
public static ArrayList<CadastraEscolas> groups;
private ArrayList<ArrayList<Filhos>> child = new ArrayList();
private HashMap<String, GPSEscolas> aMap = new HashMap<String, GPSEscolas>();
private HashMap<String, GPSEscolas> HashTask = new HashMap<String, GPSEscolas>();
public static ArrayList<Filhos> listchild;
private GridAdapter adapter;
private SecurePreferences Sessao;
public static CustomGridView gridView;
private SparseArray<SparseBooleanArray> checkedPositions;
private static final String LOG_TAG = ExpandListAdapter.class.getSimpleName();
public ExpandListTest(Context context, ArrayList<CadastraEscolas> groups, HashMap<String, GPSEscolas> data, SecurePreferences mSessao, HashMap<String, GPSEscolas> hashTask) {
this.context = context;
this.groups = groups;
this.aMap = data;
this.Sessao = mSessao;
checkedPositions = new SparseArray<SparseBooleanArray>();
child = new ArrayList();
if (groups != null) {
for (int i = 0; i < groups.size(); i++) {
child.add(i, groups.get(i).getalunos());
}
}
}
@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, final ViewGroup parent) {
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) context
.getSystemService(context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.gridview, null);
}
listchild = new ArrayList<Filhos>();
for (int j = 0; j < groups.get(groupPosition).getalunos().size(); j++) {
listchild.add(child.get(groupPosition).get(j));
}
gridView = (CustomGridView) convertView.findViewById(R.id.GridView_toolbar);
gridView.setExpanded(true);
adapter = new GridAdapter(context, groups, listchild, child, groupPosition, aMap, HashTask, Sessao);
gridView.setAdapter(adapter);// Adapter
gridView.setChoiceMode(CustomGridView.CHOICE_MODE_MULTIPLE);
return convertView;
}
@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) {
CadastraEscolas group = (CadastraEscolas) 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.getNome_fantasia());
return convertView;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
Android ViewGroups puede contener cualquier cantidad de Vistas, pero Views solo puede tener un ViewGroup principal, si intenta agregar una Vista que ya tiene un elemento primario, obtendrá esta excepción (de ViewGroup.addViewInner ()):
throw new IllegalStateException("The specified child already has a parent. " +
"You must call removeView() on the child''s parent first.");
Esto significa que la estructura de sus diseños es la de un árbol (no un gráfico), por lo que puede usar cualquier algoritmo de cruce de árboles para recorrer cada Vista de su diseño.
El siguiente es uno de los posibles algoritmos, que es un recorrido posterior a la orden.
Pasa por el elemento raíz, toma el primer hijo y hace una llamada recursiva para el algoritmo, luego es segundo, tercero, etc. ... cuando no quedan niños por recorrer, llama a su función de anulación de selección para el nodo.
Para el árbol en el diagrama, los nodos serán deseleccionados en este orden:
A, C, E, D, B, H, I, G, F
public void onClickTheButton(View view) {
unselectall(R.layout.your_layout);
}
public void unselectAll(View view) {
if(view instanceof ViewGroup) {
for(int ii = 0 ; ii<(ViewGroup)view.getChildrenCount(); ii++) {
unselectAll((ViewGroup)view.getChildAt(ii));
}
}
unselect(view);
}
Puede encontrar muchas otras maneras de hacerlo aquí: https://en.wikipedia.org/wiki/Tree_traversal
Es imprescindible aprender cómo funcionan esos algoritmos si desea facilitar su experiencia de programación.
cambie su método getView () de la siguiente manera.
@Override
public View getView(final int position, View convertView, final ViewGroup parent) {
holder = null;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.child_item, null);
holder = new ViewHolder();
final TextView idAluno = (TextView) convertView.findViewById(R.id.idcrianca);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.text.setText(child.get(position).getNome());
final View finalConvertView = convertView;
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (list.size() > 0) {
isChecked = filhos.get(posicaoEscola).get(position).isChecked();
if (!isChecked) {
selecao(true, position, nomeAluno, 0xFFFFFFFF, finalConvertView, View.VISIBLE);
} else {
selecao(false, position, nomeAluno, 0xFFD5672B, finalConvertView, View.GONE);
}
ex.findViewById(R.id.notificar).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
limpaSelecao(false, position, nomeAluno, 0xFFD5672B, parent, View.GONE);
}
});
}
});
return convertView;
}