Actually i have got a problem while implementing expandable Listview inside navigation view, the expandablelistview works perfectly but while i try to scroll it, the background menu items does get scroll but not the expandable listview, someone please have a look at the code and help me.
ExpandableListAdapter.java
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_group_child, null);
}
TextView txtListChild = (TextView) 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_header, 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;
}
}
my mainActivity.java class
public class MainActivity extends BaseAppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
@BindView(R.id.txt_heading_name_ma)
TextView txt_heading_name_ma;
@BindView(R.id.img_heading_ma)
ImageView img_heading_ma;
@BindView(R.id.navigation_MA)
BottomNavigationView navigation_MA;
@BindView(R.id.drawer_layout)
DrawerLayout drawer;
private View header;
private TextView txt_heading_mail, txt_heading_name;
private ImageView imageView;
private ExpandableListView expListView;
ExpandableListAdapter listAdapter;
private MainActivity activity;
private ShortingProductResponse shortingProductResponse;
ArrayList<String> listDataHeader;
HashMap<String, List<String>> listDataChild;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Fabric.with(this, new Crashlytics());
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
enableExpandableList();
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
toggle.getDrawerArrowDrawable().setColor(getColor(R.color.colorPrimary));
} else {
toggle.getDrawerArrowDrawable().setColor(getResources().getColor(R.color.colorPrimary));
}
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
expListView=(ExpandableListView)navigationView.findViewById(R.id.navList);
header = navigationView.getHeaderView(0);
header.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
replaceFragment(FragmentNames.MyAccountFragment, false, null, false, false);
navigationDrawClose();
}
});
txt_heading_mail = header.findViewById(R.id.txt_heading_mail);
txt_heading_name = header.findViewById(R.id.txt_heading_name);
imageView = header.findViewById(R.id.imageView);
replaceFragment(FragmentNames.MainFragment, false, null, true, true);
}
private void enableExpandableList() {
listDataHeader = new ArrayList<String>();
listDataChild = new HashMap<String, List<String>>();
expListView = (ExpandableListView) findViewById(R.id.navList);
prepareListData(listDataHeader, listDataChild);
listAdapter = new ExpandableListAdapter(this, listDataHeader, listDataChild);
expListView.setAdapter(listAdapter);
expListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {
return false;
}
});
// Listview Group expanded listener
expListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
@Override
public void onGroupExpand(int groupPosition) {
Toast.makeText(getApplicationContext(),
listDataHeader.get(groupPosition) + " Expanded",
Toast.LENGTH_SHORT).show();
}
});
expListView.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
@Override
public void onGroupCollapse(int groupPosition) {
Toast.makeText(getApplicationContext(),
listDataHeader.get(groupPosition) + " Collapsed",
Toast.LENGTH_SHORT).show();
}
});
expListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
Toast.makeText(
getApplicationContext(),
listDataHeader.get(groupPosition)
+ " : "
+ listDataChild.get(
listDataHeader.get(groupPosition)).get(
childPosition), Toast.LENGTH_SHORT)
.show();
return false;
}
});
}
private void prepareListData(List<String> listDataHeader, Map<String,
List<String>> listDataChild) {
listDataHeader.add("Terms and Conditions");
List<String> top = new ArrayList<String>();
top.add("Privacy");
top.add("Security");
top.add("Terms");
listDataChild.put(listDataHeader.get(0), top);
}
private void navigationDrawClose() {
if (drawer != null)
drawer.closeDrawer(GravityCompat.START);
}
@Override
protected void onStart() {
super.onStart();
initializeView();
}
@Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (item.getItemId()) {
case R.id.nav_wishlist_main:
if (isValidUser())
startWishListActivity();
Log.e(ApplicationContext.TAG, "Done");
return true;
case R.id.nav_cart_main:
startCarfInfoActivity();
Log.e(ApplicationContext.TAG, "Done");
return true;
}
return super.onOptionsItemSelected(item);
}
private void startWishListActivity() {
startActivity(new Intent(this, WishlistActivity.class));
}
private void startCarfInfoActivity() {
startActivity(new Intent(this, CartInfoActivity.class));
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
switch (item.getItemId()) {
case R.id.nav_home:
replaceFragment(FragmentNames.MainFragment, true, null, true, true);
break;
case R.id.nav_shop_now:
replaceFragment(FragmentNames.ShopNowFragment, true, null, false, false);
break;
case R.id.nav_brands:
replaceFragment(FragmentNames.BrandsFragment, true, null, false, false);
break;
case R.id.nav_holidays:
replaceFragment(FragmentNames.HolidaysFragment, true, null, false, false);
break;
case R.id.nav_search_products:
replaceFragment(FragmentNames.MyAccountFragment, true, null, false, false);
break;
case R.id.nav_new_arrival:
Log.e(ApplicationContext.TAG, "Done");
break;
case R.id.nav_wishlist:
Log.e(ApplicationContext.TAG, "Done");
break;
case R.id.nav_cart:
Log.e(ApplicationContext.TAG, "Done");
break;
case R.id.nav_my_orders:
replaceFragment(FragmentNames.MyOrdersFragment, false, null, false, false);
Log.e(ApplicationContext.TAG, "Done");
break;
case R.id.nav_abouts_us:
Log.e(ApplicationContext.TAG, "Done");
break;
case R.id.nav_contacts_us:
Log.e(ApplicationContext.TAG, "Done");
break;
case R.id.nav_testimonial:
Log.e(ApplicationContext.TAG, "Done");
break;
case R.id.nav_logout:
Logout();
Log.e(ApplicationContext.TAG, "Done");
break;
}
navigationDrawClose();
return true;
}
private FirebaseAuth mAuth;
private GoogleSignInClient gAuth;
private void Logout() {
PrefSetup.getInstance().clearPrefSetup();
mAuth = FirebaseAuth.getInstance();
mAuth.signOut();
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).requestIdToken(getString(R.string.default_web_client_id)).requestEmail().build();
gAuth = GoogleSignIn.getClient(this, gso);
gAuth.signOut();
startLoginActivity();
}
private void startLoginActivity() {
startActivity(new Intent(this, LoginUserActivity.class));
finish();
}
@Override
public void initializeView() {
super.initializeView();
navigation_MA.setOnNavigationItemSelectedListener(item -> {
switch (item.getItemId()) {
case R.id.bottom_nav_home:
replaceFragment(FragmentNames.MainFragment, false, null, true, true);
return true;
case R.id.bottom_nav_shop_now:
replaceFragment(FragmentNames.ShopNowFragment, false, null, false, false);
return true;
case R.id.bottom_nav_brands:
replaceFragment(FragmentNames.BrandsFragment, false, null, false, false);
return true;
case R.id.bottom_nav_holidays:
replaceFragment(FragmentNames.HolidaysFragment, false, null, false, false);
return true;
case R.id.bottom_nav_my_account:
replaceFragment(FragmentNames.MyAccountFragment, false, null, false, false);
return true;
}
return false;
});
setNavigationHeader();
}
private void setBottomNavigationItemSelected(int position) {
switch (position) {
case 0:
navigation_MA.setSelectedItemId(R.id.bottom_nav_home);
break;
case 1:
navigation_MA.setSelectedItemId(R.id.bottom_nav_shop_now);
break;
case 2:
navigation_MA.setSelectedItemId(R.id.bottom_nav_brands);
break;
case 3:
navigation_MA.setSelectedItemId(R.id.bottom_nav_holidays);
break;
case 4:
navigation_MA.setSelectedItemId(R.id.bottom_nav_my_account);
break;
}
}
private BaseFragment fragment;
public void replaceFragment(FragmentNames fragmentName, boolean isBottomSelected, Bundle bundle, boolean isFirst, boolean clearBackStack) {
Utilities.getInstance().hideKeyboard(this);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
if (clearBackStack) {
fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
switch (fragmentName) {
case MainFragment:
if (ApplicationContext.getInstance().getLiveFragment() != null && ApplicationContext.getInstance().getLiveFragment() instanceof MainFragment)
return;
fragment = new MainFragment();
if (isBottomSelected)
setBottomNavigationItemSelected(0);
break;
case ShopNowFragment:
if (ApplicationContext.getInstance().getLiveFragment() != null && ApplicationContext.getInstance().getLiveFragment() instanceof ShopNowFragment)
return;
fragment = new ShopNowFragment();
if (isBottomSelected)
setBottomNavigationItemSelected(1);
break;
case BrandsFragment:
if (ApplicationContext.getInstance().getLiveFragment() != null && ApplicationContext.getInstance().getLiveFragment() instanceof BrandsFragment)
return;
fragment = new BrandsFragment();
if (isBottomSelected)
setBottomNavigationItemSelected(2);
break;
case HolidaysFragment:
if (ApplicationContext.getInstance().getLiveFragment() != null && ApplicationContext.getInstance().getLiveFragment() instanceof HolidaysFragment)
return;
fragment = new HolidaysFragment();
if (isBottomSelected)
setBottomNavigationItemSelected(3);
break;
case MyAccountFragment:
if (ApplicationContext.getInstance().getLiveFragment() != null && ApplicationContext.getInstance().getLiveFragment() instanceof MyAccountFragment)
return;
fragment = new MyAccountFragment();
if (isBottomSelected)
setBottomNavigationItemSelected(4);
break;
case ProductListFragment:
if (ApplicationContext.getInstance().getLiveFragment() != null && ApplicationContext.getInstance().getLiveFragment() instanceof ProductListFragment)
return;
fragment = new ProductListFragment();
break;
case CartInfoFragment:
if (ApplicationContext.getInstance().getLiveFragment() != null && ApplicationContext.getInstance().getLiveFragment() instanceof CartInfoFragment)
return;
fragment = new CartInfoFragment();
break;
case MyOrdersFragment:
if (ApplicationContext.getInstance().getLiveFragment() != null && ApplicationContext.getInstance().getLiveFragment() instanceof MyOrdersFragment)
return;
fragment = new MyOrdersFragment();
break;
}
// if user passes the @bundle in not null, then can be added to the fragment
if (bundle != null) {
try {
fragment.setArguments(bundle);
} catch (Exception e) {
System.out.println(fragment.getArguments()); // print exception
}
}
if (!isFirst) {
ft.addToBackStack(fragment.getClass().getName() + "");
} else {
}
fragment.fragmentType = fragmentName.getValue();
ft.replace(R.id.rl_workSpace, fragment);
ft.commit();
}
public void setNavigationHeader(String imagePath, String userName, String mailId) {
if (imagePath.length() >= 1)
ApplicationContext.getInstance().loadImage(imagePath, imageView, null, R.drawable.no_image);
if (userName.length() >= 1)
txt_heading_name.setText(userName);
if (mailId.length() >= 1)
txt_heading_mail.setText(mailId);
}
public void setNavigationHeader() {
if (PrefSetup.getInstance().getUserInfo() == null || PrefSetup.getInstance().getUserInfo().getResponsedata() == null)
return;
try {
LoginResponse.Responsedata userInfo = PrefSetup.getInstance().getUserInfo().getResponsedata();
ApplicationContext.getInstance().loadImage(userInfo.getProfile_pic(), imageView, null, R.drawable.no_image);
txt_heading_name.setText(userInfo.getFirst_name() + " " + userInfo.getLast_name());
txt_heading_mail.setText(userInfo.getEmail());
} catch (Exception e) {
ApplicationContext.getInstance().catchException(e);
}
}
public void setHeader(int image, String headingText) {
if (image != 0) {
img_heading_ma.setVisibility(View.VISIBLE);
txt_heading_name_ma.setVisibility(View.GONE);
} else {
img_heading_ma.setVisibility(View.GONE);
txt_heading_name_ma.setVisibility(View.VISIBLE);
txt_heading_name_ma.setText(headingText);
}
}
public boolean isValidUser() {
if (PrefSetup.getInstance().getUserInfo() != null)
return true;
PopupUtils.getInstance().showTwoButtonDialogNoCancelable(this, getString(R.string.alert),
getString(R.string.login_error), getString(R.string.cancel), getString(R.string.login), (object, position) -> {
if (position == 1)
startLoginActivity();
});
return false;
}
}
activity_main.xml
<android.support.v4.widget.DrawerLayout
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:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="@layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer">
<ExpandableListView
android:id="@+id/navList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="left|start"
android:layout_marginTop="280dp"
android:background="@color/colorPrimary"
android:divider="@color/white"
android:dividerHeight="0.7dp"
android:indicatorRight="?android:attr/expandableListPreferredItemIndicatorRight" />
</android.support.design.widget.NavigationView>
listgroupheader.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="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/lblListHeader"
android:layout_width="match_parent"
android:layout_height="?attr/listPreferredItemHeightSmall"
android:gravity="center_vertical"
android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
android:paddingRight="?attr/listPreferredItemPaddingRight"
android:textColor="#1f2124"
android:textSize="16sp" />
list_group_child.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="8dp">
<TextView
android:id="@+id/lblListItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft" />
After a huge try, I have come to realize that expandablelistview inside a navigationview will work only if u put all the contents of the navigationview inside in the expandable listview because if u choose to use both menu and expandable listview inside the navigationview to populate the items then most probably the expamdablelistview will not be connected to header of the navigationview and it will not scroll with other items of navigationview and it will never sync to complete the format. so just add all the menuitems inside expandablelistview and make others childless to clone them like normal menu items