I have an Expandable ListView(EXLV) whose every Child Item has an EditText, And There is a Button outside the EXLV. It's been a week I'm messing with it.
I want to get values/Data entered in EditTexts on button Click. Because the values I enter are regenerated (I Don't know why).
Any Help would be very Appreciated.
Here is a Link to whole Project in case: https://drive.google.com/file/d/1YsCb23-wL_KBgj2braqT59mPezRhSS28/view?usp=sharing
MainActiviy.java:
package com.lvexpandable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Handler;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AlertDialog;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ExpandableListView.OnGroupClickListener;
import android.widget.ExpandableListView.OnGroupCollapseListener;
import android.widget.ExpandableListView.OnGroupExpandListener;
import android.widget.Toast;
public class MainActivity extends Activity {
final int snnn=1857;
Button btn;
EditText edt;
ExpandableListAdapter listAdapter;
ExpandableListView expListView;
List<String> listDataHeader;
HashMap<String, List<String>> listDataChild;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] mStrings = new String[20];
// get the listview
expListView = (ExpandableListView) findViewById(R.id.lvExp);
// preparing list data
prepareListData();
listAdapter = new ExpandableListAdapter(this, listDataHeader, listDataChild);
// setting list adapter
expListView.setAdapter(listAdapter);
}
public void btnClick(View v){
//I want to get values entered in EditTexts here. Maybe using SharedPref, in a List<> or whatever.
}
/*
* Preparing the list data
*/
private void prepareListData() {
listDataHeader = new ArrayList<>();
listDataChild = new HashMap<>();
// Adding child data
listDataHeader.add("PG");
listDataHeader.add("Nursery");
// Adding child data
List<String> pg = new ArrayList<String>();
pg.add("PG1: ");
pg.add("PG2: ");
pg.add("PG3: ");
pg.add("PG4: ");
pg.add("PG5: ");
pg.add("PG6: ");
pg.add("PG7: ");
pg.add("PG8: ");
pg.add("PG9: ");
pg.add("PG10: ");
pg.add("PG11: ");
pg.add("PG12: ");
pg.add("PG13: ");
pg.add("PG14: ");
pg.add("PG15: ");
List<String> nur = new ArrayList<String>();
nur.add("Object A ");
nur.add("Obj B: ");
nur.add("Obj C:");
listDataChild.put(listDataHeader.get(0), pg); // Header, Child data
listDataChild.put(listDataHeader.get(1), nur);
}
}
ExpandableListAdapter.java:
package com.lvexpandable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class ExpandableListAdapter extends BaseExpandableListAdapter {
private Context _context;
private List<String> _listDataHeader; // header titles
// child data in format of header title, child title
private HashMap<String, List<String>> _listDataChild;
public ExpandableListAdapter(Context context, List<String> listDataHeader,
HashMap<String, List<String>> listChildData) {
this._context = context;
this._listDataHeader = listDataHeader;
this._listDataChild = listChildData;
}
#Override
public Object getChild(int groupPosition, int childPosititon) {
return this._listDataChild.get(this._listDataHeader.get(groupPosition))
.get(childPosititon);
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
#Override
public View getChildView(int groupPosition, final int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
final String childText = (String) getChild(groupPosition, childPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.list_item, null);
}
TextView txtListChild = convertView.findViewById(R.id.lblListItem);
txtListChild.setText(childText);
return convertView;
}
#Override
public int getChildrenCount(int groupPosition) {
return this._listDataChild.get(this._listDataHeader.get(groupPosition))
.size();
}
#Override
public Object getGroup(int groupPosition) {
return this._listDataHeader.get(groupPosition);
}
#Override
public int getGroupCount() {
return this._listDataHeader.size();
}
#Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
String headerTitle = (String) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.list_group, null);
}
TextView lblListHeader = (TextView) convertView
.findViewById(R.id.lblListHeader);
lblListHeader.setTypeface(null, Typeface.BOLD);
lblListHeader.setText(headerTitle);
return convertView;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.lvexpandable.MainActivity">
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="50dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ExpandableListView
android:id="#+id/lvExp"
android:layout_width="match_parent"
android:layout_height="400dp" />
<Button
android:onClick="btnClick"
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="230dp"
android:text="Button"
tools:layout_editor_absoluteX="257dp"
tools:layout_editor_absoluteY="360dp" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
If anyone has a Confusion, Feel free to Ask :)
The Thing you are Trying to do is Certainly Possible, But Complex:
Add A Button in Every Child Item
When User types in Child 0, He Must Press that Child's Button (on Button Click, Save the value in array on index[childPosition]). In
this Way, Array[0] will have text of Child 1, Similar for Next
Children.
(Step 3 and Further are Optional)
If You Don't like this Design (as User needs to press button every time he enters a value, Refer to Step 4)
Set the Visibility of the Button(which was added in Step 1) to INVISIBLE
Add a TextWatcher (TextChangedListener) for EditText in ChildItem (It will getText entered > Save it in Array[] > Click the Button itself as Soon as User leaves the Current EditText). As:
edt.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
#Override
public void afterTextChanged(Editable editable) {
if(edt.getText().toString()==""&&edt.getText().toString().equals(null)){
}
else {
edt.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus)//Perform Click when edt loses Focus {
btn.callOnClick();
}
}
});
}
}});
Now the Button Click will be like:
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(edt.getText().toString().equals("")){
}
else {
Toast.makeText(view.getContext(),"Entered: "+edt.getText().toString(),Toast.LENGTH_SHORT).show();
myStringArray[childPosition]=edt.getText().toString();
edt.setText("");
}
}
});
Related
My code has an ExpandableListView and each child (schedule) can be deleted via a delete button in the child. I want to use a functionality of "Edit" TextView so that if the user clicks on "Edit" the Delete Buttons will be visible. I tried it on my custom adapter MainAdapter but gives me crashes. Could anyone help me?
MainAdapter.java
package com.example.easyplan;
import android.content.Context;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ImageButton;
import android.widget.TextView;
import java.util.HashMap;
import java.util.List;
public class MainAdapter extends BaseExpandableListAdapter {
private Context _context;
private List<String> listPlan; // header titles
// child data in format of header title, child title
private HashMap<String, List<String>> listScheduleMap;
ImageButton scheduleDeleteBtn;
public MainAdapter(Context context, List<String> listDataHeader,
HashMap<String, List<String>> listChildData) {
this._context = context;
this.listPlan = listDataHeader;
this.listScheduleMap = listChildData;
}
#Override
public Object getChild(int groupPosition, int childPosititon) {
return this.listScheduleMap.get(this.listPlan.get(groupPosition))
.get(childPosititon);
}
#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) {
final String childText = (String) getChild(groupPosition, childPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.schedule_group, null);
}
TextView txtListChild = (TextView) convertView
.findViewById(R.id.scheduleGroup);
scheduleDeleteBtn = convertView.findViewById(R.id.scheduleDeleteBtn);
scheduleDeleteBtn.setVisibility(View.INVISIBLE);
scheduleDeleteBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
List<String> plan = listScheduleMap.get(listPlan.get(groupPosition));
plan.remove(childPosition);
notifyDataSetChanged();
}
});
txtListChild.setText(childText);
return convertView;
}
#Override
public int getChildrenCount(int groupPosition) {
return this.listScheduleMap.get(this.listPlan.get(groupPosition))
.size();
}
#Override
public Object getGroup(int groupPosition) {
return this.listPlan.get(groupPosition);
}
#Override
public int getGroupCount() {
return this.listPlan.size();
}
#Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
String headerTitle = (String) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.plan_group, null);
}
TextView lblListHeader = (TextView) convertView
.findViewById(R.id.planGroup);
lblListHeader.setTypeface(null, Typeface.BOLD);
lblListHeader.setText(headerTitle);
return convertView;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
public void setDeleteVisibility(boolean visible){
for(int j = 0; j < getGroupCount(); j ++){
for(int i = 0; i<getChildrenCount(i); i++ ){
if(visible){
scheduleDeleteBtn.setVisibility(View.VISIBLE);
}else{
scheduleDeleteBtn.setVisibility(View.INVISIBLE);
}
}
}
}
}
PlansFragment.java
package com.example.easyplan;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ImageButton;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* A simple {#link Fragment} subclass.
*/
public class PlansFragment extends Fragment {
TextView editText;
MainAdapter mainAdapter;
ExpandableListView planExplandable;
List<String> listPlanName;
HashMap<String, List<String>> listSchedules;
TextView textView;
static int count = 0;
View view;
public PlansFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_plans_fragment, container, false);
listPlanName = new ArrayList<String>();
listSchedules = new HashMap<String, List<String>>();
// get the listview
planExplandable = (ExpandableListView) view.findViewById(R.id.plansExpandable);
textView = view.findViewById(R.id.scheduleGroup);
editText = view.findViewById(R.id.planEditText);
// preparing list data
// prepareListData();
createAPlan(3);
createAPlan(1);
createAPlan(3);
createAPlan(4);
mainAdapter = new MainAdapter(getActivity(), listPlanName, listSchedules);
// setting list adapter
planExplandable.setAdapter(mainAdapter);
//mainAdapter.setDeleteVisibility(false);
/* editText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mainAdapter.setDeleteVisibility(true);
}
});*/
return view;
}
public HashMap<String, String> getData(){
return null;
}
private void createAPlan(int sch){
listPlanName.add("Plan#"+(count+1));
List<String> schedules = new ArrayList<String>();
if(sch > 0 ){
for (int i = 1; i <= sch; i++){
schedules.add("Schedule#" + i);
}
}
listSchedules.put(listPlanName.get(count),schedules);
count++;
}
}
The child's xml has
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1.8">
<TextView
android:id="#+id/scheduleGroup"
android:layout_width="355dp"
android:layout_height="wrap_content"
android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:textColor="#android:color/black" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.2">
<ImageButton
android:id="#+id/scheduleDeleteBtn"
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:srcCompat="#drawable/delete_icon"
android:visibility="visible"
android:clickable="true"
></ImageButton>
</LinearLayout>
Inside your fragment use setOnItemClickListener() method on your listView and in overriden method make use of getFirstVisiblePosition() to subtract from the position where you will find the position of that view. then set the visibility.
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
listPosition = position - planExplandable.getFirstVisiblePosition();
if (planExplandable.getChildAt(listPosition).findViewById(R.id.yourview).getVisibility() == View.INVISIBLE) {
//Write your logic here
planExplandable.getChildAt(listPosition).findViewById(R.id.yourview).setVisibility(View.VISIBLE);
}
}
If this won't help then please paste your crash log.
I am using a fragment where i am using a GridView to generate some categories. When user selects a category i am replacing the previous fragment with a new fragment which is used to take the details of the category. But when i get back to the previous fragment where the categories are displayed i want to make the category selected on which the user previously clicked. I have tried to use selector but it is not working for me. Here goes my code.
Here is my layout xml file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="20dp"
>
<GridView
android:id="#+id/hindernisTypGridView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="auto_fit"
android:columnWidth="190dp"
android:verticalSpacing="20dp"
android:layout_below="#+id/topBar"
android:horizontalSpacing="5dp"
android:paddingLeft="32dp"
android:paddingRight="32dp"
/>
</LinearLayout>
Here is my custom xml for gridview
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools=" http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="190dp"
android:layout_height="180dp"
android:padding="2dp"
tools:ignore="MissingPrefix"
>
<TextView
android:textColor="#color/redText"
android:textSize="37.14sp"
android:layout_gravity="center_horizontal"
android:gravity="center_vertical"
android:textAlignment="center"
android:layout_width="match_parent"
android:layout_height="180dp"
android:text="OBW"
android:id="#+id/hindernisTypTextView"
fontPath="DBSansRegular.otf"
android:textAppearance="#style/DBSansRegular"
android:background="#drawable/grid_view_item_selector"
/>
</RelativeLayout>
Here is my selector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/redText" android:state_pressed="true"/>
</selector>
Here is the Fragment which is used to display the categories
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.Toast;
import com.example.anikdey.railwayapp.R;
import com.example.anikdey.railwayapp.adapters.HindernisTypGridViewAdapter;
import com.example.anikdey.railwayapp.models.HindernisTyp;
public class HindernisTypFragment extends Fragment {
private GridView projectListGridView;
private View view;
private HindernisTyp hindernisTyp;
private HindernisTypGridViewAdapter hindernisTypGridViewAdapter;
private OnHindernisTypSelectedListener hindernisTypSelectedListener;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.kategorie_wahlen_grid_view, container, false);
projectListGridView = (GridView) view.findViewById(R.id.kategoryWahlenGridView);
hindernisTyp = new HindernisTyp();
hindernisTypGridViewAdapter = new HindernisTypGridViewAdapter(getActivity().getApplicationContext(), hindernisTyp.getHindernisTyps());
projectListGridView.setAdapter(hindernisTypGridViewAdapter);
projectListGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
view.setSelected(true);
hindernisTypSelectedListener.setHindernisTyp(hindernisTyp.getHindernisTyps().get(position).getHindernisTypName());
FragmentManager fragmentManager = getActivity().getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, new DetailsFragment(),"DetailsFragment");
fragmentTransaction.addToBackStack("df");
fragmentTransaction.commit();
}
});
return view;
}
}
The adapter i have used for displaying the categories in gridview
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.anikdey.railwayapp.R;
import com.example.anikdey.railwayapp.models.HindernisTyp;
import java.util.ArrayList;
import java.util.List;
public class HindernisTypGridViewAdapter extends BaseAdapter {
private Context context;
private List<HindernisTyp> hindernisTyps = new ArrayList<HindernisTyp>();
public HindernisTypGridViewAdapter(Context context, List<HindernisTyp> hindernisTyps){
this.context = context;
this.hindernisTyps = hindernisTyps;
}
#Override
public int getCount() {
return hindernisTyps.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
private static final class ViewHolder {
private TextView hindernisTypTextView;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.hindernis_typ_grid_view_custom_layout, null, true);
holder = new ViewHolder();
holder.hindernisTypTextView = (TextView) convertView.findViewById(R.id.hindernisTypTextView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.hindernisTypTextView.setText(hindernisTyps.get(position).getHindernisTypName());
return convertView;
}
}
When user going to details fragment send that selected category to main activity or shared preference or constant but not try to rely on onSaveInstanceState()
Now when you return to a fragment from the back stack it does not re-create the fragment but re-uses the same instance and starts with onCreateView() in the fragment lifecycle, see Fragment Lifecycle.
Now start form onCreateView()
So add a boolean isRestoredFromBackstack to fragment and follow code below:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mIsRestoredFromBackstack = false;
}
#Override
public void onResume()
{
super.onResume();
if(mIsRestoredFromBackstack)
{
// The fragment restored from backstack,
// get selected state and set category selected again!
}
}
#Override
public void onDestroyView()
{
super.onDestroyView();
mIsRestoredFromBackstack = true;
}
OR
there is another simple solution.... depends on situation
just use add() not replace()
Fragment fragment=new DestinationFragment();
FragmentManager fragmentManager = getFragmentManager();
android.app.FragmentTransaction ft=fragmentManager.beginTransaction();
ft.add(R.id.content_frame, fragment);
ft.hide(SourceFragment.this);
ft.addToBackStack(SourceFragment.class.getName());
ft.commit();
Here is the way by which i have solved my problem. Before starting the new fragment i am storing the position in a variable named previousPosition which was initialized whit a negative value of -1. Then i am passing the previousPosition in the Adapter. The code is given below.
The updated Fragment class
package com.example.anikdey.railwayapp.fragments;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.Toast;
import com.example.anikdey.railwayapp.R;
import com.example.anikdey.railwayapp.adapters.HindernisTypGridViewAdapter;
import com.example.anikdey.railwayapp.models.HindernisTyp;
public class HindernisTypFragment extends Fragment {
private GridView projectListGridView;
private View view;
private HindernisTyp hindernisTyp;
private HindernisTypGridViewAdapter hindernisTypGridViewAdapter;
private OnHindernisTypSelectedListener hindernisTypSelectedListener;
private int previousPosition = -1;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.kategorie_wahlen_grid_view, container, false);
projectListGridView = (GridView) view.findViewById(R.id.kategoryWahlenGridView);
hindernisTyp = new HindernisTyp();
hindernisTypGridViewAdapter = new HindernisTypGridViewAdapter(getActivity().getApplicationContext(), hindernisTyp.getHindernisTyps(), previousPosition);
projectListGridView.setAdapter(hindernisTypGridViewAdapter);
projectListGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
hindernisTypSelectedListener.setHindernisTyp(hindernisTyp.getHindernisTyps().get(position).getHindernisTypName());
hindernisTypSelectedListener.enableCancelButton(true);
previousPosition = position;
FragmentManager fragmentManager = getActivity().getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, new DetailsFragment(),"DetailsFragment");
fragmentTransaction.addToBackStack("df");
fragmentTransaction.commit();
}
});
return view;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
hindernisTypSelectedListener = (OnHindernisTypSelectedListener) activity;
} catch (ClassCastException e) {
}
}
public interface OnHindernisTypSelectedListener {
public void setHindernisTyp(String hindernisTyp);
public void enableCancelButton(boolean state);
}
}
Here is the updated Adapter class
package com.example.anikdey.railwayapp.adapters;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.anikdey.railwayapp.R;
import com.example.anikdey.railwayapp.models.HindernisTyp;
import java.util.ArrayList;
import java.util.List;
public class HindernisTypGridViewAdapter extends BaseAdapter {
private Context context;
private int previousPosition;
private List<HindernisTyp> hindernisTyps = new ArrayList<HindernisTyp>();
public HindernisTypGridViewAdapter(Context context, List<HindernisTyp> hindernisTyps, int previousPosition){
this.context = context;
this.hindernisTyps = hindernisTyps;
this.previousPosition = previousPosition;
}
#Override
public int getCount() {
return hindernisTyps.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
private static final class ViewHolder {
private TextView hindernisTypTextView;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.hindernis_typ_grid_view_custom_layout, null, true);
holder = new ViewHolder();
holder.hindernisTypTextView = (TextView) convertView.findViewById(R.id.hindernisTypTextView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if(position == previousPosition) {
holder.hindernisTypTextView.setBackgroundColor(context.getResources().getColor(R.color.redText));
holder.hindernisTypTextView.setTextColor(context.getResources().getColor(R.color.whiteText));
holder.hindernisTypTextView.setText(hindernisTyps.get(position).getHindernisTypName());
} else {
holder.hindernisTypTextView.setText(hindernisTyps.get(position).getHindernisTypName());
}
return convertView;
}
}
I am creating an app in android studios that requires the user to select a child item from an expandable listview on one activity and for it to be displayed on another activity. I'm new to java and android studios and still dont understand how to do this really. If anyone has any sample code or can help that would be great, thanks!
You should use the setOnChildClickListener method from the ExpandableListView class to create a ClickListener for the list elements and then use a Intent to open the new activity. The call to set the listener should be set after you've set the adapter for the ListView.
Here there's a tutorial for using a ExpandableListView and it shows how to set a ClickListener for the elements.
And here there's the Android developer's documentation which shows how to create and open a new Activity from a button's click.
**You should use the setOnChildClickListener method from the ExpandableListView class to create a ClickListener for the list elements and then use a Intent to open the new activity. The call to set the listener should be set after you've set the adapter for the ListView and create the xml file for child and parent.child will be Expandable TextView **
**layout file**
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.elite_android.explistview1.MainActivity">
<RelativeLayout
android:id="#+id/main_number_picker_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="17dp">
<NumberPicker
android:id="#+id/main_number_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="Next" />
<TextView
android:id="#+id/main_txt_patient_count"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="#id/main_number_picker"
android:text="Select number of patient"
android:textColor="#color/colorAccent"
android:layout_marginLeft="80dp"/>
</RelativeLayout>
<ExpandableListView
android:id="#+id/exp_Listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/main_number_picker_layout">
</ExpandableListView>
</RelativeLayout>
**Main Activity.java file**
package com.example.elite_android.explistview1;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.view.View.OnFocusChangeListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ListView;
import android.widget.NumberPicker;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.NumberPicker;
public class MainActivity extends AppCompatActivity {
ExpandableListView expandableListView;
private MyAdapter mAdapter;
ExpandableListView expand;
NumberPicker numberPicker;
private List<String> headerItems;
private ArrayList childDetails;
private HashMap<String, List<String>> childList;
private Context ctx;
EditText editText1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// get reference to the EditText
editText1 = (EditText) findViewById(R.id.child_item);
// //set the onFocusChange listener
// // editText1.setOnFocusChangeListener(editText1.getOnFocusChangeListener());
//
//// //get reference to EditText
//// editText2 = (EditText) findViewById(R.id.sequence);
//// // set the on focusChange listner
//// editText2.setOnFocusChangeListener(editText2.getOnFocusChangeListener());
//
// //Generate list View from ArrayList;
//
//
// EditText editText = (EditText) findViewById(R.id.child_item);
// editText.requestFocus();
// InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
// imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
//
//
//// editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
// // #Override
// // public void onFocusChange(View v, boolean hasFocus) {
// // //editText.setOnFocusChangeListener();
// // return;
// // }
// //});
//
String[] numbers = new String[10];
for (int count = 0; count < 10; count++)
numbers[count] = String.valueOf(count);
numberPicker = (NumberPicker) findViewById(R.id.main_number_picker);
numberPicker.setMaxValue(numbers.length);
numberPicker.setMinValue(1);
numberPicker.setDisplayedValues(numbers);
numberPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
#Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
generateListItems(newVal);
loadRecycleView();
}
});
}
private void generateListItems(int childCount) {
if (headerItems != null)
headerItems.clear();
else
headerItems = new ArrayList<>();
if (childList != null)
childList.clear();
else
childList = new HashMap();
if (childDetails == null) {
childDetails = new ArrayList();
childDetails.add("Name");
childDetails.add("Age");
childDetails.add("Gender");
}
// Put header items
for (int count = 0; count < childCount; count++) {
headerItems.add(" Parent " + count);
childList.put(headerItems.get(count), childDetails);
}
}
private void loadRecycleView() {
if (expandableListView == null) {
expandableListView = (ExpandableListView) findViewById(R.id.exp_Listview);
mAdapter = new MyAdapter(this, headerItems, childList);
expandableListView.setAdapter(mAdapter);
} else {
expandableListView.invalidate();
mAdapter.setHeaderData(headerItems);
mAdapter.setListData(childList);
mAdapter.notifyDataSetChanged();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
}
**Adapter class.java**
package com.example.elite_android.explistview1;
import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.NumberPicker;
import android.widget.TextView;
import android.widget.EditText;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.view.View.OnFocusChangeListener;
/**
* Created by ELITE-ANDROID on 28-02-2017.
*/
// this is provides all needs methods implementing an Expandable List VIew
public class MyAdapter extends BaseExpandableListAdapter {
// We need some Variables here so therer are some Variables here
private List<String> header_titles; // This is for Representing the HeadLine(Array list)
private HashMap<String, List<String>> child_titles; // defin the HashMap for the child item how to Represent the Parent Handing so Hash Map, need some Variables
private Context ctx;
private NumberPicker numberPicker;
EditText editText;
View view;
private static LayoutInflater inflater = null;
//for initalized for all Variables we need some Constructor
public MyAdapter(Context context, List<String> header_titles, HashMap<String, List<String>> child_titles) {
super();
this.ctx = context;
this.child_titles = child_titles;
this.header_titles = header_titles;
}
public void refreshHeader_titles(List<String> events) {
this.header_titles.clear();
this.header_titles.addAll(header_titles);
notifyDataSetChanged();
}
;
#Override
// From this Override method How to Return how many elements are the Group count like parent
public int getGroupCount() {
return header_titles.size();
}
#Override
//here the number of child items are in each heading. There are three Heading - PAtien Name ,Age, Gender
public int getChildrenCount(int groupPosition) {
// Log.d("xxx", )
return child_titles.get(header_titles.get(groupPosition)).size(); //how to Return the size of HashMap
}
#Override
public Object getGroup(int groupPosition) {
return header_titles.get(groupPosition);
}
#Override
// here how to retuen child items on the particular headings and Positions.
public Object getChild(int groupPosition, int childPosition) {
return child_titles.get(header_titles.get(groupPosition)).get(childPosition);
}
#Override
//return the groupo position
public long getGroupId(int groupPosition) {
return groupPosition;
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
// Here return the Group View
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
// ListViewHolder viewHolder;
// if (view == null) {
// viewHolder = new ListViewHolder();
// LayoutInflater inflater = context.getLayoutInflater();
// view = inflater.inflate(R.layout.listitems, null, true);
// viewHolder.itmName = (TextView) view.findViewById(R.id.Item_name);
// viewHolder.itmPrice = (EditText) view.findViewById(R.id.Item_price);
// view.setTag(viewHolder);
// } else {
// viewHolder = (ListViewHolder) view.getTag();
//// loadSavedValues();
// }
// Here how to get the Heading Title here Decalered String Variables, now how to get title of heading from getGroup methods so simple call Backed Methods.
String title = (String) this.getGroup(groupPosition);
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) this.ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.prent, null);
}
TextView textView = (TextView) convertView.findViewById(R.id.heading_item);
textView.setText(title); // for Heading bold style ,title
return convertView;
}
#Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
String title = (String) this.getChild(groupPosition, childPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.child, null);
}
String cellData = child_titles.get(header_titles.get(groupPosition)).get(childPosition);
EditText childItem = (EditText) convertView.findViewById(R.id.child_item);
childItem.setHint(cellData);
childItem.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
// Log.d("xxxx", "Has focus " + hasFocus);
if (!hasFocus) {
// int itemIndex = View.getId();
// String enteredName = ((EditText)v).getText().toString();
// selttems.put(itemIndex, enteredName);
} else {
}
return;
}
});
return convertView;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
public void setListData(HashMap<String, List<String>> lData) {
child_titles = lData;
}
public void setHeaderData(List<String> hData) {
header_titles = hData;
}
}
**child.Xml file**
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#ffff">
<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/child_item"
android:textSize="25dp"
android:textStyle="bold"
android:gravity="center_vertical"
android:layout_marginLeft="10dp"/>
<!--<EditText-->
<!--android:id="#+id/sequence"-->
<!--android:layout_width="wrap_content"-->
<!--android:layout_height="wrap_content"-->
<!--android:layout_alignParentLeft="true"-->
<!--android:layout_alignParentTop="true"-->
<!--android:paddingLeft="35sp"-->
<!--android:layout_marginRight="10dp"-->
<!--android:textAppearance="?android:attr/textAppearanceMedium" />-->
</LinearLayout>
<!--This Layout File Represent the Child Items.
This Field Represent the Child Item IN the List VIew -->
**parent.Xml**
<?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="50dp"
android:orientation="vertical">
<TextView
android:id="#+id/heading_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:gravity="center_vertical"
android:textColor="#color/colorAccent"
android:textSize="25dp" />
</LinearLayout>
<!--This Layout file for Heading -Lines.-->
I made an ExpandableListView and now I want to set different images in each group. For example, in the Dress group I want to set a photo of a dress, in Shoes a photo of a shoe etc.
Here is my layout:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="#ffffff"
android:clickable="true"
android:orientation="vertical"
android:paddingLeft="40dp"
android:paddingStart="40dp"
tools:context=".MainActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="39dp"
android:gravity="center_vertical">
<ImageView android:id="#+id/image1"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginLeft="25dp"/>
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:textIsSelectable="true"
android:textColor="#f30f30"
android:textSize="24sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
code:
package com.example.user.expandablelist;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.CheckedTextView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
public class MyExpandableAdapter extends BaseExpandableListAdapter {
private Activity activity;
private ArrayList<Object> childtems;
private LayoutInflater inflater;
private ArrayList<String> parentItems, child;
public MyExpandableAdapter(ArrayList<String> parents, ArrayList<Object> childern) {
this.parentItems = parents;
this.childtems = childern;
}
public void setInflater(LayoutInflater inflater, Activity activity) {
this.inflater = inflater;
this.activity = activity;
}
#Override
public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
child = (ArrayList<String>) childtems.get(groupPosition);
TextView textView = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.group, null);
}
textView = (TextView) convertView.findViewById(R.id.textView1);
textView.setText(child.get(childPosition));
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(activity, child.get(childPosition),
Toast.LENGTH_SHORT).show();
}
});
return convertView;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.row, null);
}
((CheckedTextView) convertView).setText(parentItems.get(groupPosition));
((CheckedTextView) convertView).setChecked(isExpanded);
return convertView;
}
#Override
public Object getChild(int groupPosition, int childPosition) {
return null;
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return 0;
}
#Override
public int getChildrenCount(int groupPosition) {
return ((ArrayList<String>) childtems.get(groupPosition)).size();
}
#Override
public Object getGroup(int groupPosition) {
return null;
}
#Override
public int getGroupCount() {
return parentItems.size();
}
#Override
public void onGroupCollapsed(int groupPosition) {
super.onGroupCollapsed(groupPosition);
}
#Override
public void onGroupExpanded(int groupPosition) {
super.onGroupExpanded(groupPosition);
}
#Override
public long getGroupId(int groupPosition) {
return 0;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}
}
code:
package com.example.user.expandablelist;
import android.app.ExpandableListActivity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.widget.ExpandableListView;
import java.util.ArrayList;
public class MainActivity extends ExpandableListActivity {
private ArrayList<String> parentItems = new ArrayList<>();
private ArrayList<Object> childItems = new ArrayList<>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ExpandableListView expandableList = getExpandableListView();
expandableList.setDividerHeight(2);
expandableList.setGroupIndicator(null);
expandableList.setClickable(true);
setGroupParents();
setChildData();
MyExpandableAdapter adapter = new MyExpandableAdapter(parentItems, childItems);
adapter.setInflater((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE), this);
expandableList.setAdapter(adapter);
expandableList.setOnChildClickListener(this);
}
public void setGroupParents() {
parentItems.add("Shorts" );
parentItems.add("Trousers");
parentItems.add("Skirts");
parentItems.add("Dresses");
parentItems.add("Shoes");
}
public void setChildData() {
// Shirts
ArrayList<String> child = new ArrayList<>();
child.add("Basic T-Shirts" );
child.add("Printed T-shirts");
child.add("Tops");
child.add("Long-Sleeved Shirts");
childItems.add(child);
// Trousers
child = new ArrayList<>();
child.add("Jeans");
child.add("Casual");
child.add("Business");
child.add("Shorts");
child.add("Leggings");
childItems.add(child);
// Skirts
child = new ArrayList<>();
child.add("Mini");
child.add("Maxi");
child.add("Midi");
childItems.add(child);
// Dresses
child = new ArrayList<>();
child.add("Mini");
child.add("Maxi");
child.add("Midi");
child.add("Weddings & Parties");
childItems.add(child);
// Shoes
child = new ArrayList<>();
child.add("Sneakers");
child.add("High-Heels");
child.add("Wedges");
child.add("Sandals");
childItems.add(child);
}
}
Use linear layout with custom row.
This video gives a detailed explanation https://youtu.be/AT_FvelNE_Q
Public view getView (int position, View convert, ViewGroup parent){
View customView = [INSERT INFLATER METHOD);
string single =getItem(position);
TextView yourtext =(TextView) customView.findViewById (R.id.text);
ImageView image = (ImageView)customView.findViewById (R.id.image);
Image.setImageResource (R.drawable.picofcat);
yourtext.setText ("ayy lmao");
}
I want to use ExpandableListView inside ScrollView with other views but i faced the problem of self scroller in ExpandableListView l tried to disable it but the problem is with the height of the ExpandableListView and the layout it's inside.
So i want to
Disable ExpandableListView scroll
Resize ExpandableListView & LinearLayout that contains when groupView is clicked
I googled a solution and i found one for that works for ListView only
Listview in ScrollView
I want to make the same workout but with ExpandableListView (with custom Adapter).
Here is My Code:
MainActivity.java
package fablabegypt.android.expandablelistview2;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ExpandableListView;
import android.widget.LinearLayout;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class MainActivity extends ActionBarActivity {
mListAdapter listAdapter;
ExpandableListView expListView;
LinearLayout linearLayout;
List<String> listDataHeader;
HashMap<String, List<String>> listDataChild;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
linearLayout = (LinearLayout) findViewById(R.id.linear_holder);
prepareListData();
expListView = (ExpandableListView) findViewById(R.id.expand_list);
//expListView.setScrollContainer(false);
expListView.setHorizontalScrollBarEnabled(false);
expListView.setVerticalScrollBarEnabled(false);
expListView.setFastScrollEnabled(false);
expListView.setSmoothScrollbarEnabled(false);
//expListView.setOverscrollHeader(null);
expListView.setFooterDividersEnabled(false);
//expListView.setOverscrollFooter(null);
//expListView.setVerticalFadingEdgeEnabled(false);
//expListView.setHorizontalFadingEdgeEnabled(false);
expListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
return true;
}
});
expListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
if (parent.isGroupExpanded(groupPosition)) {
parent.collapseGroup(groupPosition);
} else {
parent.expandGroup(groupPosition);
}
//telling the listView we have handled the group click, and don't want the default actions.
return true;
}
});
expListView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
return false;
}else {
}
return true;
}
});
listAdapter = new mListAdapter(this, listDataHeader,listDataChild);
expListView.setAdapter(listAdapter);
}
private void prepareListData() {
listDataHeader = new ArrayList<String>();
listDataChild = new HashMap<String, List<String>>();
// Adding child data
listDataHeader.add("Top 250");
listDataHeader.add("Now Showing");
listDataHeader.add("Coming Soon..");
// Adding child data
List<String> top250 = new ArrayList<String>();
top250.add("The Shawshank Redemption");
top250.add("The Godfather");
top250.add("The Godfather: Part II");
top250.add("Pulp Fiction");
top250.add("The Good, the Bad and the Ugly");
top250.add("The Dark Knight");
top250.add("12 Angry Men");
List<String> nowShowing = new ArrayList<String>();
nowShowing.add("The Conjuring");
nowShowing.add("Despicable Me 2");
nowShowing.add("Turbo");
nowShowing.add("Grown Ups 2");
nowShowing.add("Red 2");
nowShowing.add("The Wolverine");
List<String> comingSoon = new ArrayList<String>();
comingSoon.add("2 Guns");
comingSoon.add("The Smurfs 2");
comingSoon.add("The Spectacular Now");
comingSoon.add("The Canyons");
comingSoon.add("Europa Report");
listDataChild.put(listDataHeader.get(0), top250); // Header, Child data
listDataChild.put(listDataHeader.get(1), nowShowing);
listDataChild.put(listDataHeader.get(2), comingSoon);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
}
mListAdapter.java
package fablabegypt.android.expandablelistview2;
import android.content.Context;
import android.database.DataSetObserver;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListAdapter;
import android.widget.TextView;
import java.util.HashMap;
import java.util.List;
/**
* Created by Mouso on 4/27/2015.
*/
public class mListAdapter extends BaseExpandableListAdapter {
private Context context;
private List<String> header_list;
private HashMap<String, List<String>> children_data_list;
public mListAdapter(Context context,List<String> header_list,HashMap<String,List<String>> children_data_list){
this.context = context;
this.header_list = header_list;
this.children_data_list = children_data_list;
}
#Override
public void registerDataSetObserver(DataSetObserver observer) {
}
#Override
public void unregisterDataSetObserver(DataSetObserver observer) {
}
#Override
public int getGroupCount() {
return this.children_data_list.size();
}
#Override
public int getChildrenCount(int groupPosition) {
return this.children_data_list.get(this.header_list.get(groupPosition)).size();
}
#Override
public Object getGroup(int groupPosition) {
return this.header_list.get(groupPosition);
}
#Override
public Object getChild(int groupPosition, int childPosition) {
return this.children_data_list.get(this.header_list.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 false;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
final String headerText = (String) getGroup(groupPosition);
if (convertView == null){
LayoutInflater layoutInflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.list_group,null);
}
TextView headerTxt = (TextView) convertView.findViewById(R.id.list_group_txt);
headerTxt.setTextSize(20);
headerTxt.setText(headerText);
//Log.d("Mouso",headerText);
return convertView;
}
#Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
final String childText = (String) getChild(groupPosition,childPosition);
if (convertView == null){
LayoutInflater layoutInflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.list_item,null);
}
TextView childTxt = (TextView) convertView.findViewById(R.id.list_child_txt);
childTxt.setText(childText);
return convertView;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}
#Override
public boolean areAllItemsEnabled() {
return true;
}
#Override
public boolean isEmpty() {
if (header_list.size() > 0)
return true;
return false;
}
#Override
public void onGroupExpanded(int groupPosition) {
}
#Override
public void onGroupCollapsed(int groupPosition) {
}
#Override
public long getCombinedChildId(long groupId, long childId) {
return (groupId*100)+childId;
}
#Override
public long getCombinedGroupId(long groupId) {
return groupId;
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity">
<ScrollView
android:layout_width="wrap_content"
android:layout_height="500px"
android:fillViewport="true">
<LinearLayout
android:id="#+id/linear_holder"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/txt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="we 7yat 3neak we fadaha 3neya \n\n\n dana ba7ebak ad 3naya"/>
<ExpandableListView
android:id="#+id/expand_list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:isScrollContainer="false">
</ExpandableListView>
</LinearLayout>
</ScrollView>
</RelativeLayout>
list_group.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/list_group_txt"
android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/list_child_txt"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
My Try for implmenting the workout
Helper.java
package fablabegypt.android.expandablelistview2;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ListAdapter;
import android.widget.ListView;
/**
* Created by Mouso on 4/29/2015.
*/
public class ListViewHelper {
public static void getListViewSize(ExpandableListView myListView) {
ListAdapter myListAdapter = myListView.getAdapter();
if (myListAdapter == null) {
//do nothing return null
return;
}
//set listAdapter in loop for getting final size
int totalHeight = 0;
for (int groupSize = 0; groupSize < myListAdapter.getGroupCount(); groupSize++) {
View listItem = myListAdapter.getGroupView(groupSize, false, null, myListView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
for (int size = 0; size < myListAdapter.getChildrenCount(groupSize); size++) {
if (size == myListAdapter.getChildrenCount(groupSize)-1)
listItem = myListAdapter.getChildView(groupSize, size, true, null, myListView);
listItem = myListAdapter.getChildView(groupSize, size, false, null, myListView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
}
//setting listview item in adapter
ViewGroup.LayoutParams params = myListView.getLayoutParams();
params.height = totalHeight + (myListView.getDividerHeight() * (myListAdapter.getGroupCount() - 1));
myListView.setLayoutParams(params);
// print height of adapter on log
Log.d("mouso", "height of listItem:"+String.valueOf(totalHeight));
}
//Read more: http://www.androidhub4you.com/2012/12/listview-into-scrollview-in-android.html#ixzz3Yh4m4MPG
}
Extend the ExpandableListView class and set expand to false
public class CustomExpandableListView extends ExpandableListView {
boolean expanded = false;
public CustomExpandableListView (Context context) {
super(context);
}
public CustomExpandableListView (Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomExpandableListView (Context context, AttributeSet attrs,int defStyle) {
super(context, attrs, defStyle);
}
public boolean isExpanded() {
return expanded;
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (isExpanded()) {
int expandSpec = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public void setExpanded(boolean expanded) {
this.expanded = expanded;
}
}
In your activity class
CustomExpandableListView customExpandableListView = (CustomExpandableListView ) findViewById(R.id.expandable_list);
customExpandableListView .setExpanded(true);
Layout file
<com.xxx.xxx.util.ExpandableHeightListView
android:id="#+id/expandable_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
Now It will work within a scroll view
I have same problemm
I solve this problem adding header and footer in ExpandableListView
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ExpandableListView
android:id="#+id/listview"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ExpandableListView>
</LinearLayout>
</ScrollView>
/// add header
ExpandableListView listview
ViewGroup headerView = (ViewGroup) getLayoutInflater().inflate(R.layout.item_header, listview, false);
listview.addHeaderView(headerView_right);
*/// add footer*
ViewGroup footerview= (ViewGroup) getLayoutInflater().inflate(R.layout.item_footer, listview, false);
listview.addFooterView(headerView_right);
It is ALWAYS a very bad idea to put a view that has it's own scrolling functionality inside another view with scrolling functionality. This can lead to touch actions being intercepted by the wrong view, poor performance, etc. Also, from your main layout, you don't seem to be using the ScrollView for anything other than making the TextView scroll with the list view. Why not add it as a header view? expListView.setHeaderView(View) and inflate the textview into it.
As I can see in your "activity_main.layout" I think you want to put the ExpandableListView to make the textview scroll always with the List, isn't it?
You have two solutions.
-The prettiest and easiest solution is to put the textview as a header of the ExpandableListView using
list.addHeaderView(listHeader,null,false);
important: Using "false" as the third the header can't be clicked as a row.
-The other solution is to call "getListViewSize()" every time you call "parent.collapseGroup(groupPosition)" or "parent.expandGroup(groupPosition);"
I know using a listview inside a scrollview is not recommended but sometimes is useful. Unfortunately this isn't that case, I recommend to use the first solution.
I hope I could help you.