Extensible ListView Elements Blend

So, I made this application for dream analysis, and it works very well on phones, but on tablets the information in experiments is mixed, as you can see in the figure below.

That is, when you click on a group, it should hide / show its children, but, as you can see, on tablets it just continues to draw information one on another, since the display does not update the contents, I have no idea what to do, thereby asking you for help.

device-2016-10-26-094550.png

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> 

Group item 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> 

Child 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> 

Operation 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; } } } 
+6
source share
4 answers

Well, I found the answer, and here it is - you must explicitly set the background for the layout, and it does not matter if you install it in explist or root, it must be installed.

It did not start working with any of the proposed solutions, unless I set the background in the action layout that explist contains.

An interesting question - why does this work ?!

0
source

I was able to get it to work, but the error I was getting was slightly different from yours.

When I tried to use your layouts (minus resources that I didnโ€™t have), ImageButton in both group_element.xml and child_element.xml somehow captured MotionEvent in the whole line (when they shouldn't) and in my case it was messing around with layout extension.

Decision. I just have two ImageButton for two ImageView and build OnTouchListener for two views. As you can see, it works on the Nexus 7 emulator.

Since I do not have data and, most importantly, the adapter code, I canโ€™t say for sure that this will fix your problem.

enter image description here

Ps in case you are interested. I checked your XML on the custom version of the JournalDev adapter example on ExpandableListViews :

 import java.util.HashMap; import java.util.List; import android.content.Context; import android.graphics.Typeface; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.BaseExpandableListAdapter; import android.widget.ImageView; import android.widget.TextView; public class CustomExpandableListAdapter extends BaseExpandableListAdapter { private Context context; private List<String> expandableListTitle; private HashMap<String, List<String>> expandableListDetail; public CustomExpandableListAdapter(Context context, List<String> expandableListTitle, HashMap<String, List<String>> expandableListDetail) { this.context = context; this.expandableListTitle = expandableListTitle; this.expandableListDetail = expandableListDetail; } @Override public Object getChild(int listPosition, int expandedListPosition) { return this.expandableListDetail.get(this.expandableListTitle.get(listPosition)) .get(expandedListPosition); } @Override public long getChildId(int listPosition, int expandedListPosition) { return expandedListPosition; } @Override public View getChildView(int listPosition, final int expandedListPosition, boolean isLastChild, View convertView, ViewGroup parent) { final String expandedListText = (String) getChild(listPosition, expandedListPosition); if (convertView == null) { //--------------------------------------------- LayoutInflater layoutInflater = (LayoutInflater) this.context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = layoutInflater.inflate(R.layout.child_element, null); } TextView expandedListTextView = (TextView) convertView .findViewById(R.id.textChild); expandedListTextView.setText(expandedListText); ImageView editViewBtn = (ImageView)convertView.findViewById(R.id.sExp_BtnEdit); editViewBtn.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { // do stuff return false; } }); return convertView; } @Override public int getChildrenCount(int listPosition) { return this.expandableListDetail.get(this.expandableListTitle.get(listPosition)) .size(); } @Override public Object getGroup(int listPosition) { return this.expandableListTitle.get(listPosition); } @Override public int getGroupCount() { return this.expandableListTitle.size(); } @Override public long getGroupId(int listPosition) { return listPosition; } @Override public View getGroupView(int listPosition, boolean isExpanded, View convertView, ViewGroup parent) { String listTitle = (String) getGroup(listPosition); if (convertView == null) { LayoutInflater layoutInflater = (LayoutInflater) this.context. getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = layoutInflater.inflate(R.layout.group_element, null); } TextView listTitleTextView = (TextView) convertView .findViewById(R.id.textGroup); listTitleTextView.setTypeface(null, Typeface.BOLD); listTitleTextView.setText(listTitle); ImageView addV = (ImageView)convertView.findViewById(R.id.sExp_BtnAdd); addV.setVisibility(View.VISIBLE); addV.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { // do stuff return false; } }); return convertView; } @Override public boolean hasStableIds() { return false; } @Override public boolean isChildSelectable(int listPosition, int expandedListPosition) { return true; } } 

Dummy data generator:

 import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class ExpandableListDataPump { public static HashMap<String, List<String>> getData() { HashMap<String, List<String>> expandableListDetail = new HashMap<String, List<String>>(); List<String> ego = new ArrayList<String>(); ego.add("dream 1"); ego.add("dream 2"); ego.add("dream 3"); ego.add("dream 4"); ego.add("dream 5"); List<String> personalities = new ArrayList<String>(); personalities.add("dream 1"); personalities.add("dream 2"); personalities.add("dream 3"); personalities.add("dream 4"); List<String> places = new ArrayList<String>(); places.add("dream 1"); places.add("dream 2"); places.add("dream 3"); places.add("dream 4"); places.add("dream 5"); expandableListDetail.put("Form of the ego", ego); expandableListDetail.put("Form of other personalities", personalities); expandableListDetail.put("Place form", places); return expandableListDetail; } } 

Primary activity:

 import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.ExpandableListAdapter; import android.widget.ExpandableListView; import android.widget.Toast; import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class Main4Activity extends AppCompatActivity { ExpandableListView expandableListView; ExpandableListAdapter expandableListAdapter; List<String> expandableListTitle; HashMap<String, List<String>> expandableListDetail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); expandableListView = (ExpandableListView) findViewById(R.id.sExpList); expandableListDetail = ExpandableListDataPump.getData(); expandableListTitle = new ArrayList<>(expandableListDetail.keySet()); expandableListAdapter = new CustomExpandableListAdapter(this, expandableListTitle, expandableListDetail); expandableListView.setAdapter(expandableListAdapter); expandableListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() { @Override public void onGroupExpand(int groupPosition) { Toast.makeText(getApplicationContext(), expandableListTitle.get(groupPosition) + " List Expanded.", Toast.LENGTH_SHORT).show(); } }); expandableListView.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() { @Override public void onGroupCollapse(int groupPosition) { Toast.makeText(getApplicationContext(), expandableListTitle.get(groupPosition) + " List Collapsed.", Toast.LENGTH_SHORT).show(); } }); expandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { Toast.makeText( getApplicationContext(), expandableListTitle.get(groupPosition) + " -> " + expandableListDetail.get( expandableListTitle.get(groupPosition)).get( childPosition), Toast.LENGTH_SHORT ).show(); return false; } }); } } 

Your slightly modified main xml, do not forget to switch from ImageButton to ImageView : (I changed some resources and dimensions that you did not share)

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

Xml group:

 <?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="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="17dp" android:layout_marginTop="2dp" android:layout_weight="7" android:textStyle="bold" android:textSize="13sp" /> <ImageView android:id="@+id/sExp_BtnAdd" android:layout_width="25dp" android:layout_height="25dp" android:layout_gravity="center_vertical" android:contentDescription="" android:focusable="false" android:scaleType="centerCrop" android:src="@android:drawable/ic_input_add" /> </LinearLayout> 

child xml:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" 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="?android:attr/expandableListPreferredItemPaddingLeft" android:layout_marginTop="2dp" android:textColor="@android:color/white" android:layout_weight="1" android:textSize="13sp" /> <ImageView android:layout_width="20dp" android:layout_height="20dp" android:layout_marginEnd="?android:attr/expandableListPreferredItemPaddingLeft" android:id="@+id/sExp_BtnEdit" android:layout_gravity="center_vertical" android:src="@android:drawable/ic_menu_edit" android:scaleType="centerCrop" android:focusable="false" android:layout_marginRight="5dp" /> </LinearLayout> 

Uff ... it was long, hope this helps!

0
source

You tried to set the root layout parameters in both list items from

 android:layout_height="match_parent" 

to

 android:layout_height="wrap_content" 

?

0
source

Android is designed for multiple screens, so sometimes a single layout file might not support some screens well. Suggestion can help you:

make some changes to the original layout file, make it on the tablet on the right, then save and place the adjusted file in the appropriate directory as follows:

  res/layout/my_layout.xml // layout for normal screen size ("default") res/layout-large/my_layout.xml // layout for large screen size res/layout-xlarge/my_layout.xml // layout for extra-large screen size res/layout-xlarge-land/my_layout.xml // layout for extra-large in landscape orientation 

And xlarge screens are at least 960dp x 720dp, large screens are at least 640dp x 480dp, normal screens are at least 470dp x 320dp, small screens are at least 426dp x 320dp.

White papers on this topic, https://developer.android.com/guide/practices/screens_support.html#qualifiers

What I consider the best solution for working with unusual behavior on ordinary layouts.

0
source

Source: https://habr.com/ru/post/1011705/


All Articles