我使用this示例实现了ExpandableListView,与代码和示例代码相比,唯一的2个差异是:我在对话框上实现而不是活动,而2个差异是我的数据来自SQLite。
因此,我成功实现了ExpandableListView,并且根据组/子pos数据也处于理想位置。代码没有问题。
现在,稍后我在同一ExpandableListAdapter中实现了搜索功能。
问题::假设我要搜索电力(在我的情况下,“ E”在两次以上都匹配两次)因此,当我搜索“ E”时,它会显示我有一个与“ E”匹配的列表,这很好,但是当我输入第二个字母“ L”时,它在getChild方法上崩溃,并告诉我索引为“ 1”,大小为“ 1”,我知道应该为2 ,但我不知道怎么可能?因为当它向我展示ExpandableList时,相同的getChild方法也可以工作!
我也尝试调试,主要组的大小是第一次正确,但是后来仍然为零(0)。
请参阅:
代码:
对话框类:
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.tekitsolutions.remindme.Adapter.CustomSpinnerAdapter;
import com.tekitsolutions.remindme.Adapter.CustomSpinnerClass;
import com.tekitsolutions.remindme.Adapter.DialogListAdapter;
import com.tekitsolutions.remindme.Adapter.ExpandableCategoryAdapter;
import com.tekitsolutions.remindme.Interface.CategoryListener;
import com.tekitsolutions.remindme.Interface.HamburgerMenuListener;
import com.tekitsolutions.remindme.Interface.ResultListener;
import com.tekitsolutions.remindme.Model.CategoryHeader;
import com.tekitsolutions.remindme.Model.CategoryResponse;
import com.tekitsolutions.remindme.Model.CustomCategory;
import com.tekitsolutions.remindme.Model.General;
import com.tekitsolutions.remindme.Model.ProvidersInfo;
import com.tekitsolutions.remindme.Model.Reminder;
import com.tekitsolutions.remindme.R;
import com.tekitsolutions.remindme.RestApi.ApiClient;
import com.tekitsolutions.remindme.RestApi.ApiInterface;
import com.tekitsolutions.remindme.Sql.DatabaseAdapter;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import static android.content.Context.MODE_PRIVATE;
import static com.tekitsolutions.remindme.Sql.DataBaseConstant.CUSTOM_CATEGORY_ID;
import static com.tekitsolutions.remindme.Sql.DataBaseConstant.PROVIDER_CATEGORY_ID;
import static com.tekitsolutions.remindme.Sql.DataBaseConstant.PROVIDER_ID;
import static com.tekitsolutions.remindme.Sql.DataBaseConstant.REMINDER_CATEGORY_ACCOUNT_NUMBER;
import static com.tekitsolutions.remindme.Sql.DataBaseConstant.REMINDER_CATEGORY_ALIAS_NAME;
import static com.tekitsolutions.remindme.Sql.DataBaseConstant.REMINDER_CATEGORY_ID;
import static com.tekitsolutions.remindme.Sql.DataBaseConstant.REMINDER_CATEGORY_OWNER_NAME;
import static com.tekitsolutions.remindme.Sql.DataBaseConstant.REMINDER_CATEGORY_PROVIDER_ID;
import static com.tekitsolutions.remindme.Sql.DataBaseConstant.REMINDER_CATEGORY_PROVIDER_NAME;
import static com.tekitsolutions.remindme.Sql.DataBaseConstant.REMINDER_CATEGORY_PROVIDER_NUMBER;
import static com.tekitsolutions.remindme.Sql.DataBaseConstant.REMINDER_CATEGORY_SUB_PROVIDER_ID;
import static com.tekitsolutions.remindme.Sql.DataBaseConstant.SUB_PROVIDER_ID;
import static com.tekitsolutions.remindme.Utils.CommonUtils.CUSTOM_HEADER;
import static com.tekitsolutions.remindme.Utils.CommonUtils.ELECTRICITY_BILL;
import static com.tekitsolutions.remindme.Utils.CommonUtils.ELECTRICITY_BILL_ID;
import static com.tekitsolutions.remindme.Utils.CommonUtils.GAS;
import static com.tekitsolutions.remindme.Utils.CommonUtils.GAS_ID;
import static com.tekitsolutions.remindme.Utils.CommonUtils.GENERAL_HEADER;
import static com.tekitsolutions.remindme.Utils.CommonUtils.INSURANCE;
import static com.tekitsolutions.remindme.Utils.CommonUtils.INSURANCE_ID;
import static com.tekitsolutions.remindme.Utils.CommonUtils.LANDLINE;
import static com.tekitsolutions.remindme.Utils.CommonUtils.LANDLINE_ID;
import static com.tekitsolutions.remindme.Utils.CommonUtils.NO_CATEGORY;
import static com.tekitsolutions.remindme.Utils.CommonUtils.OTHER_HEADER;
import static com.tekitsolutions.remindme.Utils.CommonUtils.PHONE_NUMBER;
import static com.tekitsolutions.remindme.Utils.CommonUtils.PICK_PROVIDER_CODE;
import static com.tekitsolutions.remindme.Utils.CommonUtils.PROFILE;
import static com.tekitsolutions.remindme.Utils.CommonUtils.RESULT_FAILED;
import static com.tekitsolutions.remindme.Utils.CommonUtils.RESULT_OKAY;
import static com.tekitsolutions.remindme.Utils.CommonUtils.WATER_BILL;
import static com.tekitsolutions.remindme.Utils.CommonUtils.WATER_BILL_ID;
public class CategoryDialog extends BaseClass implements View.OnClickListener, Callback<String>, HamburgerMenuListener, ResultListener {
private static final String TAG = CategoryDialog.class.getSimpleName();
int i = 0;
private String landlineName, getProviderName, defaultName = "", phoneNum, customCategoryName, selected = "", getConsumerNum, getAccountNum, getOwnerName;
private long tempId = 0, categoryId, getCustomCategoryId, providerId, customCategoryId = 0, subProviderId;
private boolean stop = true, insurance, isEditPayment = false, isDeletedSQLite = false, isDeletedServer = false, isClicked = false;
private ExpandableCategoryAdapter expandableCategoryAdapter;
private List<CustomCategory> categories, customCategories;
private RecyclerView dialogRecyclerView;
private ExpandableListView expandableListView;
private DatabaseAdapter dbAdapter;
private Context context;
private SharedPreferences profilePreference;
private View promptsView;
private CustomCategory customCategory;
private List<Reminder> dialogListItems;
private ImageView info, search, close;
private DialogListAdapter dialogListAdapter;
private Activity activity;
private ProviderDialog providerDialog;
private TextView categoryToolbar, title, inputInsuranceProvider, textViewError, inputBillProvider, errorView, information, subProviderError, providerError, customProviderError, consumerError, ownerError;
private EditText searchText, userInput, inputConsumerNumber, name, inputAccountNumber, inputCustomProvider;
private ProvidersInfo providersInfo;
private AlertDialog informationDialog, mDialog;
private CategoryListener categoryListener;
private General provider, subProvider;
private RelativeLayout relativeProvider, subProviderLayout, accountLayout, customLayout;
private LinearLayout spinnerLayout;
private List<General> mainInsuranceList = new ArrayList<>();
private CustomSpinnerAdapter spinnerAdapter;
private CustomSpinnerClass spinInsuranceList;
private ArrayList<CategoryHeader> headerArrayList = new ArrayList<CategoryHeader>();
private CategoryHeader categoryHeader;
public CategoryDialog(Context context, Activity activity) {
super(context, activity);
this.activity = activity;
this.context = context;
}
private void init() {
categories = new ArrayList<>();
customCategories = new ArrayList<>();
dbAdapter = RemindMe.getInstance().adapter;
search = promptsView.findViewById(R.id.search);
close = promptsView.findViewById(R.id.close);
categoryToolbar = promptsView.findViewById(R.id.category_toolbar);
searchText = promptsView.findViewById(R.id.search_text);
dialogListItems = new ArrayList<>();
profilePreference = context.getSharedPreferences(PROFILE, MODE_PRIVATE);
providerDialog = new ProviderDialog(context);
providerDialog.setResultListener(this);
getDataFromSharedPref();
}
private void search() {
searchText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
expandableCategoryAdapter.filterData(s.toString());
if (count == 0) {
if (headerArrayList.size() == 0) {
loadSomeData();
}
expandAll();
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
private void loadSomeData() {
categoryHeader = new CategoryHeader(GENERAL_HEADER, categories);
headerArrayList.add(categoryHeader);
categoryHeader = new CategoryHeader(OTHER_HEADER, categories);
headerArrayList.add(categoryHeader);
categoryHeader = new CategoryHeader(CUSTOM_HEADER, customCategories);
headerArrayList.add(categoryHeader);
}
public void setCategoryListener(CategoryListener listener) {
this.categoryListener = listener;
}
private void setClickListener() {
search.setOnClickListener(this);
close.setOnClickListener(this);
}
public void showCategoryDialog() {
LayoutInflater li = LayoutInflater.from(context);
promptsView = li.inflate(R.layout.row_category_dialog_layout, null);
init();
findViewById();
setClickListener();
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
alertDialogBuilder.setView(promptsView);
alertDialogBuilder.setPositiveButton(context.getString(R.string.add), null);
alertDialogBuilder.setNegativeButton(context.getString(R.string.cancel), null);
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.setCancelable(false);
recyclerView();
search();
mDialog = alertDialogBuilder.create();
mDialog.setCancelable(false);
mDialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
Button button = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE);
Button buttonNegative = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_NEGATIVE);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
isEditPayment = false;
showDialogBox(0);
}
});
buttonNegative.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
}
});
mDialog.show();
}
private void findViewById() {
expandableListView = promptsView.findViewById(R.id.expandableList);
}
private void recyclerView() {
loadArrayListData();
expandableCategoryAdapter = new ExpandableCategoryAdapter(context, headerArrayList, this);
try {
expandableListView.setAdapter(expandableCategoryAdapter);
} catch (Exception exp) {
exp.printStackTrace();
}
}
//method to expand all groups
private void expandAll() {
int count = expandableCategoryAdapter.getGroupCount();
for (int i = 0; i < count; i++) {
expandableListView.expandGroup(i);
}
}
ExpandableListAdapter:
import android.content.Context;
import android.content.res.Resources;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.tekitsolutions.remindme.Interface.HamburgerMenuListener;
import com.tekitsolutions.remindme.Model.CategoryHeader;
import com.tekitsolutions.remindme.Model.CustomCategory;
import com.tekitsolutions.remindme.R;
import com.tekitsolutions.remindme.Utils.CommonUtils;
import java.util.ArrayList;
import java.util.List;
public class ExpandableCategoryAdapter extends BaseExpandableListAdapter {
private static final String TAG = ExpandableCategoryAdapter.class.getSimpleName();
private Context context;
private List<CategoryHeader> originalList;
private List<CategoryHeader> headerList;
private HamburgerMenuListener menuInterface;
public ExpandableCategoryAdapter(Context context, List<CategoryHeader> generalList, HamburgerMenuListener menuInterface) {
this.context = context;
this.headerList = new ArrayList<CategoryHeader>();
this.headerList.addAll(generalList);
this.originalList = generalList;
this.menuInterface = menuInterface;
}
@Override
public Object getChild(int groupPosition, int childPosition) {
List<CustomCategory> countryList = headerList.get(groupPosition).getCategoryList();
return countryList.get(childPosition);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
Resources resources = context.getResources();
CustomCategory customCategory = (CustomCategory) getChild(groupPosition, childPosition);
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.row_general_list, null);
}
TextView name = convertView.findViewById(R.id.tv_category_item);
ImageView icon = convertView.findViewById(R.id.iv_category_icon);
Button logo = convertView.findViewById(R.id.iv_custom_category_icon);
ImageView hamburgerMenu = convertView.findViewById(R.id.hamburger_menu);
if (customCategory != null) {
if (customCategory.getCustCategoryName() != null) {
name.setText(customCategory.getCustCategoryName().trim());
}
if (customCategory.getIcon() != null && customCategory.getCustCategoryId() <= CommonUtils.WATER_BILL_ID) {
icon.setVisibility(View.VISIBLE);
logo.setVisibility(View.GONE);
hamburgerMenu.setVisibility(View.GONE);
icon.setImageResource(resources.getIdentifier(customCategory.getIcon(), "drawable",
context.getPackageName()));
} else {
icon.setVisibility(View.GONE);
logo.setVisibility(View.VISIBLE);
hamburgerMenu.setVisibility(View.VISIBLE);
logo.setText(customCategory.getCustCategoryName().substring(0, 1));
}
}
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
menuInterface.onClickListItem(headerList.get(groupPosition).getCategoryList().get(childPosition).getCustCategoryId());
}
});
hamburgerMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (menuInterface != null) {
menuInterface.onClickHamburger(headerList.get(groupPosition).getCategoryList().get(childPosition).getCustCategoryId());
}
}
});
return convertView;
}
@Override
public int getChildrenCount(int groupPosition) {
if (headerList.get(groupPosition).getHeaderName().equals(CommonUtils.GENERAL_HEADER)) {
return CommonUtils.LANDLINE_ID;
}
if (headerList.get(groupPosition).getHeaderName().equals(CommonUtils.OTHER_HEADER)) {
return CommonUtils.WATER_BILL_ID;
}
return headerList.get(groupPosition).getCategoryList().size();
}
@Override
public Object getGroup(int groupPosition) {
return headerList.get(groupPosition);
}
@Override
public int getGroupCount() {
return headerList.size();
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
private void showLog(String msg) {
Log.d(TAG, msg);
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View view, ViewGroup parent) {
CategoryHeader categoryHeader = (CategoryHeader) getGroup(groupPosition);
if (view == null) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(R.layout.row_custom_category_list, null);
}
TextView heading = view.findViewById(R.id.header_view);
heading.setText(categoryHeader.getHeaderName().trim());
return view;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
public void filterData(String query) {
query = query.toLowerCase();
headerList.clear();
if (query.isEmpty()) {
headerList.addAll(originalList);
} else {
for (CategoryHeader categoryHeader : originalList) {
List<CustomCategory> categoryList = categoryHeader.getCategoryList();
List<CustomCategory> newList = new ArrayList<CustomCategory>();
for (CustomCategory customCategory : categoryList) {
if (customCategory.getCustCategoryName().toLowerCase().contains(query)) {
newList.add(customCategory);
}
}
if (newList.size() > 0) {
CategoryHeader nContinent = new CategoryHeader(categoryHeader.getHeaderName(), newList);
headerList.add(nContinent);
}
}
}
notifyDataSetChanged();
}
}
答案 0 :(得分:0)
通过根据标题名称添加单独的arraylist来解决。还在数据库中添加了字段/标签。
private void loadSomeData() {
List<CustomCategory> generalCategories = new ArrayList<>();
generalCategories.addAll(dbAdapter.getCategoryById(null, 0, GENERAL_HEADER));
List<CustomCategory> otherCategories = new ArrayList<>();
otherCategories.addAll(dbAdapter.getCategoryById(null, 0, OTHER_HEADER));
categoryHeader = new CategoryHeader(GENERAL_HEADER, generalCategories);
headerArrayList.add(categoryHeader);
categoryHeader = new CategoryHeader(OTHER_HEADER, otherCategories);
headerArrayList.add(categoryHeader);
categoryHeader = new CategoryHeader(CUSTOM_HEADER, customCategories);
headerArrayList.add(categoryHeader);
}