Movsar Bekaev Movsar Bekaev - 1 month ago 8
Android Question

ExpandableListView's items get blended

So I've made this application for dreams analysis and it works very well on the phones, but on tablets the information in explists get blended as you can see in the picture below.

That is, when you click on the group it should hide / show its children, but as you see, on tablets it just continues drawing the information one upon the other, like the display won't refresh its contents, I have no idea what to do, thus asking you for help.

device-2016-10-26-094550.png

The container layout:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="10dp">


<ExpandableListView
android:id="@+id/sExpList"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:groupIndicator="@null" />

<!-- FOR PORTRAIT LAYOUTS !-->
<FrameLayout
android:id="@+id/adLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:layout_marginTop="5dp"
android:baselineAligned="false"
android:orientation="vertical"/>
</LinearLayout>


The group element code:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>

<TextView
android:id="@+id/textGroup"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="20dp"
android:layout_weight="1"
android:textStyle="bold"
android:textSize="@dimen/text_normal_size" />

<ImageButton

android:id="@+id/sExp_BtnAdd"
android:layout_width="@dimen/btns_heigh"
android:layout_height="@dimen/btns_heigh"
android:layout_gravity="center_vertical"
android:contentDescription=""
android:focusable="false"
android:scaleType="centerCrop"
android:src="?attr/img_add" />

</LinearLayout>


The child element code:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/textChild"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:textColor="@android:color/white"
android:layout_weight="1"
android:textSize="@dimen/text_normal_size" />

<ImageButton
android:layout_width="@dimen/btns_heigh"
android:layout_height="@dimen/btns_heigh"
android:id="@+id/sExp_BtnEdit"
android:layout_gravity="center_vertical"
android:src="?attr/img_edit"
android:scaleType="centerCrop"
android:focusable="false"
android:layout_marginRight="@dimen/btns_heigh" />


</LinearLayout>


Activity code:

import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;

/**
* Created with IntelliJ IDEA.
* User: Movsar Bekaev
* Date: 11.06.13
* Time: 7:30
* To change this template use File | Settings | File Templates.
*/
public class ActSignsManager extends cbActivity {


ExpandableListView expListView;

int selected_type;
String[] cats;
ArrayList<xSign> MySigns;
_sManagerExpAdapter adapter;


String[] catsMind;
String[] catsAction;
String[] catsForm;
String[] catsCircumstances;


private void cInitialization() {
setContentView(R.layout.alay_signs_manager);

catsMind = getResources().getStringArray(R.array.smanager_cats_mind);
catsAction = getResources().getStringArray(R.array.smanager_cats_action);
catsForm = getResources().getStringArray(R.array.smanager_cats_form);
catsCircumstances = getResources().getStringArray(R.array.smanager_cats_circumstances);

expListView = (ExpandableListView) findViewById(R.id.sExpList);

newSignFunc();
readSigns();
expFiller();
adapter.notifyDataSetChanged();


expListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
String s = MySigns.get(SignIndexAt(selected_type, groupPosition, adapter.getChild(groupPosition, childPosition).toString())).getTitle();
Toast.makeText(ActSignsManager.this, String.valueOf(s), Toast.LENGTH_LONG).show();
return false;
}
});
expListView.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
String menuItems[];
ExpandableListView.ExpandableListContextMenuInfo info =
(ExpandableListView.ExpandableListContextMenuInfo) menuInfo;
int type = ExpandableListView.getPackedPositionType(info.packedPosition);
int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition);
int childPos = ExpandableListView.getPackedPositionChild(info.packedPosition);

if (type == 0) {

menuItems = getResources().getStringArray(R.array.exp_menu_ongroup);
menu.setHeaderTitle(adapter.getGroupText(groupPos));
for (int i = 0; i < menuItems.length; i++) {
menu.add(Menu.NONE, i, i, menuItems[i]);
}
}
if (type == 1) {
String s = adapter.getChild(groupPos, childPos).toString();
menuItems = getResources().getStringArray(R.array.exp_menu_onchild);
menu.setHeaderTitle(s);
for (int i = 0; i < menuItems.length; i++) {
menu.add(Menu.NONE, i, i, menuItems[i]);
}
}
}
});

}

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(R.style.DarkTheme);
cInitialization();

}

@Override
public boolean onContextItemSelected(MenuItem item) {
ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) item.getMenuInfo();
int menuItemIndex = item.getItemId();
int type = ExpandableListView.getPackedPositionType(info.packedPosition);
int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition);
int childPos = ExpandableListView.getPackedPositionChild(info.packedPosition);

if (type == 0) {

switch (menuItemIndex) {
case 0:
Intent i = new Intent(ActSignsManager.this, ActSignsAddNew.class);
ps_int_params.put("Type", selected_type);
ps_string_arr_params.put("Categories", cats);
ps_int_params.put("Selected_Item", groupPos);

if (IS_FREE_VERSION && MySigns.size() > 69)
Toast.makeText(ActSignsManager.this, getString(R.string.ruefully_you_cant_add_another_sign), Toast.LENGTH_LONG).show();
else startActivity(i);

break;
}
}
if (type == 1) {
int index = SignIndexAt(selected_type, groupPos, adapter.getChild(groupPos, childPos).toString());

switch (menuItemIndex) {
case 0:
// Toast.makeText(sManager.this, "edit", 5000).show();
Intent i = new Intent(ActSignsManager.this, ActSignsAddNew.class);

ps_int_params.put("ID", MySigns.get(index).getID());
ps_string_params.put("Name", MySigns.get(index).getTitle());
ps_int_params.put("Type", MySigns.get(index).getType());
ps_int_params.put("Category", MySigns.get(index).getCategory());
ps_string_params.put("Note", MySigns.get(index).getNote());
ps_string_arr_params.put("Categories", cats);


startActivity(i);
break;
}
}

return true;
}

// нажатие на элемент

void newSignFunc() {
String type = ps_string_params.get("Type");
if (type.equals("Mind")) {
cats = catsMind;
selected_type = 0;
}
if (type.equals("Action")) {
cats = catsAction;
selected_type = 1;
}
if (type.equals("Form")) {
cats = catsForm;
selected_type = 2;
}
if (type.equals("Circumstances")) {
cats = catsCircumstances;
selected_type = 3;
}

}

private void readSigns() {
MySigns = new ArrayList<xSign>();

Cursor c = ps_db.query(const_tbl_signs, null, null, null, null, null, null);
if (c != null) {
if (c.moveToFirst()) {
do {
xSign iSingleSign = new xSign();
iSingleSign.setID(c.getInt(DBI_SIGNS_ID));
iSingleSign.setHash(c.getString(DBI_SIGNS_HASH));
iSingleSign.setTitle(c.getString(DBI_SIGNS_TITLE));
iSingleSign.setType(c.getInt(DBI_SIGNS_TYPE));
iSingleSign.setCategory(c.getInt(DBI_SIGNS_CATEGORY));
iSingleSign.setNote(c.getString(DBI_SIGNS_NOTE));
MySigns.add(iSingleSign);
Log.d("777", iSingleSign.getID() + "||| cat:" + iSingleSign.getCategory() + "||| type:" + iSingleSign.getType());
} while (c.moveToNext());
c.close();
} else
Log.d("777", "0 rows");
}


}


private int SignIndexAt(int type, int category, String name) {
boolean exist = false;
int index = -1;
for (int i = 0; i < this.MySigns.size(); i++) {
if (this.MySigns.get(i).getTitle().equals(name) && this.MySigns.get(i).getCategory() == category && this.MySigns.get(i).getType() == type) {
index = i;
exist = true;
}
}
if (exist) {
return index;
} else {
return 999999;
}
}

private boolean removeSign(int index) {
ps_db.delete(const_tbl_signs, "id = " + MySigns.get(index).getID(), null);

Toast.makeText(ActSignsManager.this, getString(R.string.messages_sign_removed), Toast.LENGTH_LONG).show();
// Refresh main activity upon close of dialog box

readSigns();
expFiller();

adapter.notifyDataSetChanged();
return true;
}

private void expFiller() {
ArrayList<String> tmp;
ArrayList<ArrayList<String>> groups = new ArrayList<ArrayList<String>>();
for (int i = 0; i < cats.length; i++) {
tmp = new ArrayList<String>();
for (xSign sign : MySigns) {
if (sign.getCategory() == i && sign.getType() == selected_type)
tmp.add(sign.getTitle());
}
groups.add(tmp);
}
//Создаем адаптер и передаем context и список с данными
adapter = new _sManagerExpAdapter(this, cats, groups);
expListView.setAdapter(adapter);
}

@Override
public void onResume() {
super.onResume();
cInitialization();
showAds();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
cInitialization();
showAds();
}

public class _sManagerExpAdapter extends BaseExpandableListAdapter {

private ArrayList<ArrayList<String>> mGroups;
private Context mContext;
private String[] cats;

public _sManagerExpAdapter(Context context, String[] categories, ArrayList<ArrayList<String>> groups) {
mContext = context;
mGroups = groups;
cats = categories;
}


public String getGroupText(int groupPosition) {
return cats[groupPosition];
}

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

@Override
public int getChildrenCount(int groupPosition) {
return mGroups.get(groupPosition).size();
}

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

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

@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}

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

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

@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.s_exp_group_view, null);
}

if (isExpanded) {
//Изменяем что-нибудь, если текущая Group раскрыта
} else {
//Изменяем что-нибудь, если текущая Group скрыта
}

TextView textGroup = (TextView) convertView.findViewById(R.id.textGroup);
textGroup.setText(cats[groupPosition] + " [" + String.valueOf(this.getChildrenCount(groupPosition)) + "]");

ImageView btnAddSigns = (ImageView) convertView.findViewById(R.id.sExp_BtnAdd);
btnAddSigns.setFocusable(false);
final int gPos = groupPosition;

btnAddSigns.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent i = new Intent(ActSignsManager.this, ActSignsAddNew.class);
ps_int_params.put("Type", selected_type);
ps_string_arr_params.put("Categories", cats);
ps_int_params.put("Selected_Item", gPos);

if (IS_FREE_VERSION && MySigns.size() > 69)
Toast.makeText(ActSignsManager.this, getString(R.string.ruefully_you_cant_add_another_sign), Toast.LENGTH_LONG).show();
else startActivity(i);
}
});

return convertView;

}

@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.s_exp_child_view, null);
}

TextView textChild = (TextView) convertView.findViewById(R.id.textChild);
textChild.setText(mGroups.get(groupPosition).get(childPosition));

final int index = SignIndexAt(selected_type, groupPosition, adapter.getChild(groupPosition, childPosition).toString());

ImageView btnEditSign = (ImageView) convertView.findViewById(R.id.sExp_BtnEdit);
btnEditSign.setFocusable(false);


btnEditSign.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent i = new Intent(ActSignsManager.this, ActSignsAddNew.class);

ps_int_params.put("ID", MySigns.get(index).getID());
ps_string_params.put("Name", MySigns.get(index).getTitle());
ps_int_params.put("Type", MySigns.get(index).getType());
ps_int_params.put("Category", MySigns.get(index).getCategory());
ps_string_params.put("Note", MySigns.get(index).getNote());
ps_string_arr_params.put("Categories", cats);
startActivity(i);
}
});


return convertView;
}

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


}

Answer

Well I have found the answer, and here it is - you should explicitly set a background for the layout, and it is not important whether you set it to explist or root element, it just must be set.

It didn't start to work with any of proposed solutions unless I had set a background in the activity's layout which holds the explist.

Interesting question - why does this work?!