Please forgive me for my bad English. I'm new to Android and I have a problem maintaining the scroll position in an ExpandableViewList when making a selection. My application displays an ExpandableList with clickable objects, allowing these objects to be added to a basket. When I click on a product to add it to the basket, the ExpandableViewList is refreshed and as a result I lose the scroll position. The scroll goes back to position parent 0 child 0. I can't find a solution to maintain the position.
This my view activity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_flux_stock_listing);
expandableListFluxStock = findViewById(R.id.expandableListOfFluxStock);
expandablePanierChargement = findViewById(R.id.expandableListChargement);
actionWasteLoading = findViewById(R.id.actionWasteLoading);
getSupportFragmentManager()
.beginTransaction()
.add(R.id.fragment_flux_listing_bottom, barcodeScanner.getFragmentClass(), savedInstanceState)
.commit();
checkAuthorizedUser();
loadDataFromStore();
initPanierChargement();
initFluxStockList();
if (savedInstanceState == null) {
synchronizeFromSiteSelectionActivity();
}
}
@Override
protected void onResume() {
super.onResume();
barcodeScanner.onResume();
}
@Override
protected void onPause() {
super.onPause();
barcodeScanner.onPause();
}
protected void initFluxStockList() {
expandableListFluxStock.setTag(TO_UPDATE);
expandableListFluxStock.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
if (TO_UPDATE.equals(expandableListFluxStock.getTag())) {
fluxStockListAdapter = new ExpandableFluxStockListAdapter(this, storageZones, fluxByStorageZone, storageEntriesAExpedier);
expandableListFluxStock.setAdapter(fluxStockListAdapter);
expandableListFluxStock.setTag(UPDATED);
}
});
expandableListFluxStock.setOnChildClickListener((parent, view, storageZonePosition, stockPosition, id) -> {
StorageEntry storageEntry = requireNonNull(fluxByStorageZone.get(storageZones.get(storageZonePosition)))
.get(stockPosition);
startChargement(view, storageEntry);
return false;
});
}
public void initPanierChargement() {
panierChargementView = findViewById(R.id.panier_chargement);
if (storageEntriesAExpedier.isEmpty()) {
panierChargementView.setVisibility(GONE);
} else {
panierChargementView.setVisibility(VISIBLE);
}
}
private void startChargement(View view, StorageEntry storageEntry) {
if (EN_STOCK.equals(storageEntry.getStatutType())) {
if (isHorsPanier(storageEntry)) {
fillFluxStockAjouteLeftView(view);
ajouterAuPanierChargement(storageEntry);
} else {
supprimerDuPanierChargement(view, storageEntry);
}
}
}
public void ajouterAuPanierChargement(StorageEntry storageEntry) {
databaseService.savePanierChargementItem(storageEntry);
storageEntriesAExpedier = databaseService.findPanierChargement();
mettreAJourPanierChargement();
if (isPanierGone()) {
panierChargementView.setVisibility(VISIBLE);
}
expandableListFluxStock.setTag(TO_UPDATE);
}
private void mettreAJourPanierChargement() {
wasteNames.clear();
descriptionsByWasteName.clear();
panierChargementAdapter = new ExpandablePanierChargementAdapter(this, rendrePanierChargement(storageEntriesAExpedier));
expandablePanierChargement.setAdapter(panierChargementAdapter);
}
This is my Adapter
public ExpandableFluxStockListAdapter(Context context, List<String> listDataHeader,
Map<String, List<StorageEntry>> listChildData,
List<SimpleStorageEntry> storageEntriesAExpedier) {
this.context = context;
this.storageZones = listDataHeader;
this.fluxByStorageZone = listChildData;
this.storageEntriesAExpedier = storageEntriesAExpedier;
}
/**
* Return the zoneStorage view
*/
@Override
public View getGroupView(int storageZonePosition, boolean isExpanded, View convertView, ViewGroup parent) {
convertView = createOrRecycleStorageZoneView(convertView);
fillStorageZoneView(storageZonePosition, convertView, (ExpandableListView) parent);
return convertView;
}
private void fillStorageZoneView(int storageZonePosition, View convertView, ExpandableListView parent) {
TextView storageZoneView = (TextView) convertView.findViewById(R.id.storageZoneItem);
String storageZoneName = (String) getGroup(storageZonePosition);
storageZoneView.setText(storageZoneName);
//On affiche l'accordéon des zoneStorages déplié par défaut
parent.expandGroup(storageZonePosition);
}
/**
* Return the fluxStock view
*/
@Override
public View getChildView(int storageZonePosition, final int fluxStockPosition, boolean isLastChild, View convertView, ViewGroup parent) {
return getChildView(storageZonePosition, fluxStockPosition, convertView);
}
public View getChildView(int storageZonePosition, final int fluxStockPosition, View convertView) {
convertView = createOrRecycleFluxStockView(convertView);
final StorageEntry storageEntry = (StorageEntry) getChild(storageZonePosition, fluxStockPosition);
fillFluxStockIconLeftView(convertView, storageEntry);
fillFluxStockNameCenterView(convertView, storageEntry);
fillFluxStockNameRightView(convertView, storageEntry);
return convertView;
}
private void fillFluxStockIconLeftView(View convertView, StorageEntry storageEntry) {
int iconId;
int bgColor;
int textColor;
List<String> storageEntryAExpedierIds = storageEntriesAExpedier.stream()
.map(SimpleStorageEntry::getId)
.collect(toList());
if (EN_STOCK.equals(storageEntry.getStatutType()) && !storageEntryAExpedierIds.contains(storageEntry.getDemandId())) {
iconId = R.drawable.ic_action_flux_stock_en_stock;
bgColor = R.color.demand_enlevement;
textColor = R.color.text_standard;
} else {
iconId = R.drawable.ic_action_flux_stock_charge;
bgColor = R.color.tennaxia_blue;
textColor = R.color.text_white;
}
ImageView fluxStockIcon = convertView.findViewById(R.id.fluxStockIcon);
fluxStockIcon.setImageDrawable(context.getResources().getDrawable(iconId));
LinearLayout leftLayout = convertView.findViewById(R.id.fluxStockLeftIconView);
leftLayout.setBackgroundColor(context.getResources().getColor(bgColor));
TextView demandTypeLabelView = (TextView) convertView.findViewById(R.id.fluxStockTypeLabel);
demandTypeLabelView.setTextColor(getColor(context, textColor));
if (storageEntryAExpedierIds.contains(storageEntry.getDemandId())) {
demandTypeLabelView.setText(CHARGE.getLabel());
} else {
demandTypeLabelView.setText(storageEntry.getStatutType().getLabel());
}
}
private void fillFluxStockNameCenterView(View convertView, StorageEntry storageEntry) {
int textColor;
textColor = R.color.text_standard;
TextView fluxStockDescription = convertView.findViewById(R.id.fluxStockDescription);
fluxStockDescription.setText(generateDescription(storageEntry));
fluxStockDescription.setTextColor(getColor(context, textColor));
}
private void fillFluxStockNameRightView(View convertView, StorageEntry storageEntry) {
TextView demandFluxNumber = convertView.findViewById(R.id.fluxStockFluxNumber);
demandFluxNumber.setText(generateFluxNumber(storageEntry));
}
private Spanned generateDescription(StorageEntry storageEntry) {
return fromHtml(new FluxStockDescription(context.getResources(), storageEntry).htmlShort(), FROM_HTML_MODE_LEGACY, null, null);
}
private Spanned generateFluxNumber(StorageEntry storageEntry) {
return fromHtml(new FluxStockDescription(context.getResources(), storageEntry).htmlFluxNumber(), FROM_HTML_MODE_LEGACY, null, null);
}
@Override
public Object getChild(int storageZonePosition, int fluxStockPosition) {
return fluxByStorageZone
.get(this.storageZones.get(storageZonePosition))
.get(fluxStockPosition);
}
@Override
public long getChildId(int storageZonePosition, int fluxStockPosition) {
return fluxStockPosition;
}
@Override
public int getChildrenCount(int storageZonePosition) {
return fluxByStorageZone.get(storageZones.get(storageZonePosition)).size();
}
@Override
public Object getGroup(int storageZonePosition) {
return storageZones.get(storageZonePosition);
}
@Override
public int getGroupCount() {
return storageZones.size();
}
@Override
public long getGroupId(int storageZonePosition) {
return storageZonePosition;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public boolean isChildSelectable(int storageZonePosition, int fluxStockPosition) {
return true;
}
private View createOrRecycleFluxStockView(View convertView) {
if (convertView == null) {
convertView = createView(R.layout.list_flux_stock);
}
return convertView;
}
private View createOrRecycleStorageZoneView(View convertView) {
if (convertView == null) {
convertView = createView(R.layout.list_storage_zone);
}
return convertView;
}
private View createView(int ressource) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return layoutInflater.inflate(ressource, null);
}
And my xml view
<?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="fill_parent"
android:orientation="vertical">
<ExpandableListView
android:id="@+id/expandableListOfFluxStock"
android:layout_weight="1"
android:layout_height="0dp"
android:layout_width="match_parent"
android:cacheColorHint="#00000000"
android:groupIndicator="@null"/>
<LinearLayout
android:id="@+id/panier_chargement"
android:layout_width="match_parent"
android:layout_height="300sp"
android:orientation="vertical">
<TextView
android:id="@+id/titre_panier"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="@color/text_white"
android:background="@color/tennaxia_blue"
android:text="@string/titre_panier_chargement"
android:padding="10sp"
android:textStyle="bold"
android:textSize="17sp"/>
<ExpandableListView
android:id="@+id/expandableListChargement"
android:layout_weight="1"
android:layout_height="0dp"
android:layout_width="match_parent"
android:cacheColorHint="#00000000"
android:groupIndicator="@null"
android:divider="@null"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingBottom="5sp"
android:paddingTop="5sp">
<Button
android:id="@+id/actionWasteLoading"
android:layout_width="150sp"
android:layout_height="40sp"
android:text="@string/button_next_step"
android:textColor="@color/text_white"
android:background="@color/tennaxia_blue"
android:onClick="getWasteLoading"/>
</LinearLayout>
</LinearLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_flux_listing_bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
I found a lot of information on listView but almost none on ExpandableView
expandablelist view scrolling position => used only from listView
I am looking for ExpandableListView Auto Scroll to particular position => used with RecycleView, not possible for me.