I want to fill an ExpandableListView with a custom Adapter. What I found online is having only one child(one TextView) as a child. In my case, I want to make it have multiple child and data filled after a Background task.
Please help me find what I've done wrong or what should I do as the error as I keep on getting
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.util.HashMap.put(java.lang.Object, java.lang.Object)' on a null object reference
at com.infy.texpetrol.Activity.CreditReportActivity$GetData.onPostExecute
CreditReportActivity
public class CreditReportActivity extends AppCompatActivity {
private static final String TAG = "CreditBillActivity";
private ConnectionClass connectionClass;
private ProgressDialog progressDialog;
private List<String> cListPetrol, cListDIESEL, cListSPEED, cListOIL;
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_credit_report);
String empCode = getIntent().getStringExtra("empCode");
String shift = getIntent().getStringExtra("shift");
String date = getIntent().getStringExtra("date");
connectionClass = new ConnectionClass();
expListView = findViewById(R.id.lvExpandable);
GetData getData = new GetData();
getData.execute(empCode);
}
#SuppressLint("StaticFieldLeak")
private class GetData extends AsyncTask {
boolean bPetrolRS = false;
boolean bDesiRS = false;
boolean bSpedRS = false;
boolean bOilRS = false;
#Override
protected Object doInBackground(Object[] objects) {
String empCode = objects[0].toString();
try {
Connection con = connectionClass.CONN();
String queryPetrol, queryDIESEL, queryOIL, querySPEED;
queryDIESEL = "Some SQL QUERY";
queryPetrol = "Some SQL QUERY";
queryOIL = "Some SQL QUERY";
querySPEED = "Some SQL QUERY";
if (con != null) {
Statement statement1 = con.createStatement();
Statement statement2 = con.createStatement();
Statement statement3 = con.createStatement();
Statement statement4 = con.createStatement();
ResultSet rsPetrol = statement1.executeQuery(queryPetrol);
ResultSet rsDIESEL = statement2.executeQuery(queryDIESEL);
ResultSet rsOIL = statement3.executeQuery(queryOIL);
ResultSet rsSPEED = statement4.executeQuery(querySPEED);
listDataHeader = new ArrayList<>();
cListPetrol = new ArrayList<>();
cListDIESEL = new ArrayList<>();
cListSPEED = new ArrayList<>();
cListOIL = new ArrayList<>();
Log.d(TAG, "doInBackground: rsPetrol " + rsPetrol.next());
if (rsPetrol.next()) {
while (rsPetrol.next()) {
bPetrolRS = true;
cListPetrol.add(rsPetrol.getString("PartyName")
+ "#.#" + rsPetrol.getString("QTY")
+ "#.#" + rsPetrol.getString("Amount"));
}
} else {
bPetrolRS = false;
cListPetrol.add("NONE");
}
Log.d(TAG, "doInBackground: rsDIESEL " + rsDIESEL.next());
if (rsDIESEL.next()) {
while (rsDIESEL.next()) {
bDesiRS = true;
cListDIESEL.add(rsDIESEL.getString("PartyName")
+ "#.#" + rsDIESEL.getString("QTY")
+ "#.#" + rsDIESEL.getString("Amount"));
}
} else {
bDesiRS = false;
cListDIESEL.add("NONE");
}
Log.d(TAG, "doInBackground: rsSPEED " + rsSPEED.next());
if (rsSPEED.next()) {
while (rsSPEED.next()) {
bSpedRS = true;
cListSPEED.add(rsSPEED.getString("PartyName")
+ "#.#" + rsSPEED.getString("QTY")
+ "#.#" + rsSPEED.getString("Amount"));
}
} else {
bSpedRS = false;
cListSPEED.add("NONE");
}
Log.d(TAG, "doInBackground: rsOIL " + rsOIL.next());
if (rsOIL.next()) {
while (rsOIL.next()) {
bOilRS = true;
cListOIL.add(rsOIL.getString("PartyName")
+ "#.#" + rsOIL.getString("QTY")
+ "#.#" + rsOIL.getString("Amount"));
}
} else {
bSpedRS = false;
cListOIL.add("NONE");
}
} else {
Log.d(TAG, "doInBackground: Error in Connection");
}
} catch (Exception e) {
bPetrolRS = false;
Log.d(TAG, "doInBackground: CATCH " + e.getMessage());
}
return empCode;
}
#Override
protected void onPostExecute(Object o) {
progressDialog.hide();
if (!o.toString().isEmpty()) {
listDataHeader.add("DIESEL");
listDataHeader.add("PETROL");
listDataHeader.add("SPEED");
listDataHeader.add("OIL");
if (bDesiRS) {
Log.d(TAG, "onPostExecute: cListDIESEL " + cListDIESEL.size() + " listDataHeader.get(0) " + listDataHeader.get(0));
listDataChild.put(listDataHeader.get(0), cListDIESEL);
} else {
Toast.makeText(CreditReportActivity.this, "NO DATA IN DIESEL", Toast.LENGTH_SHORT).show();
}
if (bPetrolRS) {
Log.d(TAG, "onPostExecute: cListPetrol " + cListPetrol.size() + " listDataHeader.get(1) " + listDataHeader.get(1));
listDataChild.put(listDataHeader.get(1), cListPetrol); //error gets me here
} else {
Toast.makeText(CreditReportActivity.this, "NO DATA IN PETROL", Toast.LENGTH_SHORT).show();
}
if (bOilRS) {
listDataChild.put(listDataHeader.get(2), cListSPEED);
Log.d(TAG, "onPostExecute: cListSPEED " + cListSPEED.size());
} else {
Toast.makeText(CreditReportActivity.this, "NO DATA IN SPEED", Toast.LENGTH_SHORT).show();
}
if (bSpedRS) {
listDataChild.put(listDataHeader.get(3), cListOIL);
Log.d(TAG, "onPostExecute: cListOIL " + cListOIL.size());
} else {
Toast.makeText(CreditReportActivity.this, "NO DATA IN OIL", Toast.LENGTH_SHORT).show();
}
listAdapter = new ExpandableListAdapter(CreditReportActivity.this, listDataHeader, listDataChild);
expListView.setAdapter(listAdapter);
} else {
Toast.makeText(CreditReportActivity.this, "No Data", Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(CreditReportActivity.this);
progressDialog.setMessage("Getting your Report");
progressDialog.show();
}
}
}
ExpandableListAdapter
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;
private String[] split;
public ExpandableListAdapter(Context _context, List<String> _listDataHeader, HashMap<String, List<String>> _listDataChild) {
this._context = _context;
this._listDataHeader = _listDataHeader;
this._listDataChild = _listDataChild;
}
#Override
public Object getChild(int groupPosition, int childPosition) {
return Objects.requireNonNull(this._listDataChild.get(this._listDataHeader.get(groupPosition))).get(childPosition);
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
#SuppressLint("InflateParams")
#Override
public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
final String childText = (String) getChild(groupPosition, childPosition);
stringSplit(childText);
if (convertView == null) {
LayoutInflater Inflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = Inflater.inflate(R.layout.child, null);
}
TextView txtPartyName = convertView.findViewById(R.id.txt_C_partyName);
txtPartyName.setText(split[0]);
TextView product = convertView.findViewById(R.id.txt_C_COUNT);
product.setText(String.valueOf(childPosition));
TextView qty = convertView.findViewById(R.id.txt_C_qty);
qty.setText(split[1]);
TextView amt = convertView.findViewById(R.id.txt_C_amt);
amt.setText(split[2]);
return convertView;
}
private void stringSplit(String childText) {
split = childText.split("#.#");
}
#Override
public int getChildrenCount(int groupPosition) {
return Objects.requireNonNull(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;
}
#SuppressLint("InflateParams")
#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.header, null);
}
TextView lblListHeader = 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 false;
}
}
You forgot to initialize listDataChild
HashMap<String, List<String>> listDataChild = new HashMap<>();
Related
I have an UpdateFragment which display cards group by tags using a RecyclerView and ViewModel. In UpdateFragment I can also modify the name of the tags but I don't know why the change isn't detected by UpdateFragment until I recreate the fragment so UI don't update. The strange thing is that the MainActivity instead detect the update of the list and the code is equal.
UpdateFragment.class
public class UpdateFragment extends BaseCardFragment {
// TODO show total cards number
private static final String TAG = "UpdateFragment";
private RecyclerView recyclerView;
public UpdateFragment(List<CardWithTags> cardList, List<Tag> tagList) {
super(cardList, tagList);
}
#Override
public void updateUI(List<CardWithTags> cardListWithTags, List<Tag> tagList) {
RecyclerViewAdapterUpdate adapter = (RecyclerViewAdapterUpdate) recyclerView.getAdapter();
Log.d(TAG, "Adapter:" + adapter);
Log.d(TAG, "Cards:" + cardListWithTags);
Log.d(TAG, "Tags:" + tagList);
if (adapter != null && cardListWithTags != null && tagList != null) {
adapter.setCardList(cardListWithTags);
adapter.setTagList(tagList);
adapter.notifyDataSetChanged();
Log.d(TAG, ">>Update, Total cards: " + adapter.getItemCount());
Log.d(TAG, ">>Update, Total tags: " + tagList.size());
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_update, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setViewModel();
setRecyclerView();
}
private void setViewModel() {
Log.d(TAG, ">>SetViewModel()");
viewModel = new ViewModelProvider(this).get(ViewModelMainActivity.class);
viewModel.getAllCards().observe(getActivity(), cardListLoaded -> {
cardList = cardListLoaded;
Log.d(TAG, ">>CardList updated:" + cardList);
updateUI(cardList, tagList);
});
viewModel.getAllTags().observe(getActivity(), tagListLoaded -> {
tagList = tagListLoaded;
Log.d(TAG, ">>TagList updated:" + tagList);
updateUI(cardList, tagList);
});
}
private void setRecyclerView() {
Log.d(TAG, ">>SetRecyclerView()");
recyclerView = getView().findViewById(R.id.recycler_view_list);
RecyclerViewAdapterUpdate recyclerViewAdapter = new RecyclerViewAdapterUpdate(cardList, tagList,
getContext(), getLayoutInflater(),
viewModel);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext(),
RecyclerView.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(recyclerViewAdapter);
}
}
ViewModelMainActivity.class
public class ViewModelMainActivity extends AndroidViewModel {
private static final String TAG = "ViewModelMainActivity";
private static boolean cardListIsUpdatedWithDb = false;
private static boolean tagListIsUpdatedWithDb = false;
private LiveData<List<CardWithTags>> cardList = new MutableLiveData<>();
private LiveData<List<Tag>> tagList = new MutableLiveData<>();
private final CardDAO cardDAO;
private final ExecutorService executor;
public ViewModelMainActivity(#NonNull Application application) {
super(application);
this.cardDAO = DatabaseTaboom.getDatabase(application).cardDao();
this.executor = Executors.newSingleThreadExecutor();
}
public LiveData<List<CardWithTags>> getAllCards() {
Log.d(TAG, ">>GetAllCards()");
if (!cardListIsUpdatedWithDb) {
cardList = cardDAO.getAllCards();
cardListIsUpdatedWithDb = true;
}
return cardList;
}
public LiveData<List<Tag>> getAllTags() {
Log.d(TAG, ">>GetAllTags()");
if (!tagListIsUpdatedWithDb) {
tagList = cardDAO.getAllTags();
tagListIsUpdatedWithDb = true;
}
return tagList;
}
public void insertCard(CardWithTags card) {
Log.d(TAG, ">>InsertCard(): " + card);
executor.execute(() -> {
long idCard = cardDAO.insertCard(card.getCard());
if (idCard >= 1) {
cardListIsUpdatedWithDb = false;
Log.d(TAG, ">>Inserted Card: " + card.getCard().getTitle());
}
for (Tag t: card.getTagList()) {
long idTag = cardDAO.insertTag(t);
CardTagCrossRef cardTagCrossRef = new CardTagCrossRef();
cardTagCrossRef.idCard = idCard;
if (idTag < 1) {
// If Tag already exist, retrieve that to get id to try insert cwt
idTag = cardDAO.getTag(t.getTag()).getIdTag();
} else {
// New Tag
tagListIsUpdatedWithDb = false;
Log.d(TAG, ">>Inserted Tag: " + t.getTag());
}
cardTagCrossRef.idTag = idTag;
long idCWT = cardDAO.insertCardWithTags(cardTagCrossRef);
if (idCWT >= 1) {
Log.d(TAG, ">>Inserted CWT: [" + idCard + "," + idTag + "]");
// Tag linked to a card
cardListIsUpdatedWithDb = false;
}
}
});
}
public void shuffle(List<CardWithTags> list) {
if (list != null) {
Collections.shuffle(list);
cardList = new MutableLiveData<>(list);
Log.d(TAG, ">>List shuffled: " + list);
} else {
Log.d(TAG, ">>List is null");
}
}
public void updateTag(Tag tag) {
executor.execute(() -> {
cardDAO.updateTag(tag);
tagListIsUpdatedWithDb = false;
cardListIsUpdatedWithDb = false;
});
}
}
RecyclerViewAdapterUpdate.class
public class RecyclerViewAdapterUpdate extends RecyclerView.Adapter<RecyclerViewAdapterUpdate.ViewHolder> {
private static final String TAG = "RecyclerViewAdapterUpdate";
private List<CardWithTags> cardList;
private List<Tag> tagList;
private Context context;
private LayoutInflater layoutInflater;
private ViewModelMainActivity viewModelFragment;
public RecyclerViewAdapterUpdate(List<CardWithTags> cardList, List<Tag> tagList, Context context,
LayoutInflater layoutInflater, ViewModelMainActivity viewModelFragment) {
this.cardList = cardList;
this.tagList = tagList;
this.context = context;
this.layoutInflater = layoutInflater;
this.viewModelFragment = viewModelFragment;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_update, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
if (position == 0) {
holder.numberOfItems.setText(String.valueOf(cardList.size()));
holder.tagName.setText(R.string.all_cards_tag);
holder.clearTag.setVisibility(View.GONE);
} else {
Tag tag = tagList.get(position - 1);
List<CardWithTags> listOfSingleTag = new ArrayList<>();
for (CardWithTags cwt: cardList) {
for (Tag t: cwt.getTagList()) {
if (t.getTag().equals(tag.getTag()))
listOfSingleTag.add(cwt);
}
}
holder.numberOfItems.setText(String.valueOf(listOfSingleTag.size()));
holder.tagName.setText(tag.getTag());
View viewDialogTag = layoutInflater.inflate(R.layout.dialog_modify_tag, null);
EditText tagNameEditText = viewDialogTag.findViewById(R.id.tag_name_dialog);
tagNameEditText.setText(tag.getTag());
// In this way the dialog is created only one time
AlertDialog dialog = new AlertDialog.Builder(context)
.setView(viewDialogTag)
.setTitle(R.string.title_modify_tag)
.setPositiveButton(R.string.modify, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
String newTag = tagNameEditText.getText().toString();
if (!newTag.isEmpty()&& !newTag.equalsIgnoreCase(tag.getTag())) {
tag.setTag(newTag);
viewModelFragment.updateTag(tag);
Log.d(TAG, ">>Update TAG: " + tag.getTag() + "->" + newTag);
}
}
})
.create();
holder.tagName.setOnLongClickListener( view -> {
dialog.show();
return true;
});
holder.clearTag.setOnClickListener( v -> Log.d(TAG, ">>CLICKED"));
}
}
#Override
public int getItemCount() {
if (tagList == null)
return 1;
return tagList.size() + 1;
}
public class ViewHolder extends RecyclerView.ViewHolder {
private static final String TAG = "ViewHolder";
private final TextView numberOfItems;
private final TextView tagName;
private final Button clearTag;
private final CheckBox checkBox;
public ViewHolder(#NonNull View itemView) {
super(itemView);
numberOfItems = itemView.findViewById(R.id.number_of_items);
tagName = itemView.findViewById(R.id.tag_name);
clearTag = itemView.findViewById(R.id.clear_tag);
checkBox = itemView.findViewById(R.id.check_box);
}
}
public void setCardList(List<CardWithTags> cardList) {
this.cardList = cardList;
}
public void setTagList(List<Tag> tagList) {
this.tagList = tagList;
}
}
I don't understand why this piece of code isn't called:
viewModel.getAllCards().observe(getActivity(), cardListLoaded -> {
cardList = cardListLoaded;
Log.d(TAG, ">>CardList updated:" + cardList);
updateUI(cardList, tagList);
});
viewModel.getAllTags().observe(getActivity(), tagListLoaded -> {
tagList = tagListLoaded;
Log.d(TAG, ">>TagList updated:" + tagList);
updateUI(cardList, tagList);
});
MainActivity.class method that instead is called even if is equal to that one in UpdateFragment (the activity is the same):
private void firstLoadCardList() {
ConstraintLayout fragmentContainer = findViewById(R.id.fragment_container);
ConstraintLayout progressBarContainer = findViewById(R.id.loading_container);
fragmentContainer.setVisibility(View.GONE);
progressBarContainer.setVisibility(View.VISIBLE);
Log.d(TAG, ">>FirstLoadCardList()");
viewModel = new ViewModelProvider(this).get(ViewModelMainActivity.class);
checkIfDatabaseAlreadyExist();
viewModel.getAllCards().observe(this, cardListLoaded -> {
cardList = cardListLoaded;
Log.d(TAG, ">>Total cards found: " + cardList.size());
if (tagList != null /*&& appJustOpened*/) {
appJustOpened = false;
progressBarContainer.setVisibility(View.GONE);
fragmentContainer.setVisibility(View.VISIBLE);
bottomNav.setSelectedItemId(R.id.play_nav);
}
});
viewModel.getAllTags().observe(this, tagListLoaded -> {
tagList = tagListLoaded;
Log.d(TAG, ">>Total tags found: " + tagList.size());
// If tagList not loaded before creation of BottomNav update Fragment list
// and cardList already loaded
if (cardList!= null /*&& appJustOpened*/) {
appJustOpened = false;
progressBarContainer.setVisibility(View.GONE);
fragmentContainer.setVisibility(View.VISIBLE);
bottomNav.setSelectedItemId(R.id.play_nav);
}
});
}
Please stop talking about notifyDataSetChanged() in the comments, I know how it works, my problem is with ViewModel/observer. The part about observer shouldn't be called every time the lists of the ViewModel change? Thank you.
I think you just need to add the below function in your recycler adapter.
public void setCardList(List<CardWithTags> cardList){
this.cardList=new ArrayList<CardWithTags>()
this.cardList.addAll(cardList)
notifyDataSetChanged()
}
public void setTagList(List<Tag> tagList){
this.tagList=new ArrayList<Tag>();
this.tagList.addAll(tagList);
notifyDataSetChanged();
}
Finally I found the answer: the two observer methods were not equals. In fact both in the Activity and in the Fragment I wrote: viewModel.getAllCards().observe(this, cardListLoaded -> {...} but this is different if called from Activity or Fragment, in the Fragment I have to use requireActivity() instead.
The main problem is that when i add bookmark codes from direct recyclerview it works perfectly fine but when i add those codes to another fragment it just only show a toast that bookmark is added or deleted but that bookmarked word doesn't show in favorite list.
Here is my Database codes
public class DictionaryDB {
public static final String ID = "id";
public static final String SANSKRIT = "sanskrit_word";
public static final String BANGLA = "bn_word";
public static final String STATUS = "status";
public static final String USER = "user_created";
public static final String TABLE_NAME = "sanskrit_words";
public static final String BOOKMARKED = "b";
public static final String USER_CREATED = "u";
DatabaseInitializer initializer;
public DictionaryDB(DatabaseInitializer initializer) {
this.initializer = initializer;
}
public void addWord(String sanskritWord, String banglaWord) {
SQLiteDatabase db = initializer.getWritableDatabase();
String sql = "INSERT INTO " + TABLE_NAME + " (" + SANSKRIT +
", " + BANGLA + ", " + USER + ") VALUES ('" + sanskritWord +
"', '" + banglaWord + "', '" + USER_CREATED + "') ";
db.execSQL(sql);
}
public List<Word> getWords(String sanskritWord) {
SQLiteDatabase db = initializer.getReadableDatabase();
String sql = "SELECT * FROM " + TABLE_NAME + " WHERE " + SANSKRIT + " LIKE ? ";
Cursor cursor = null;
try {
cursor = db.rawQuery(sql, new String[]{sanskritWord + "%"});
List<Word> wordList = new ArrayList<Word>();
while(cursor.moveToNext()) {
int id = cursor.getInt(0);
String sanskrit = cursor.getString(1);
String bangla = cursor.getString(2);
String status = cursor.getString(3);
wordList.add(new Word(id, sanskrit, bangla, status));
}
return wordList;
} catch (SQLiteException exception) {
exception.printStackTrace();
return null;
} finally {
if (cursor != null)
cursor.close();
}
}
//************Waka Maka Saka *****************//******************//
public List<Word> getBookmarkedWords() {
SQLiteDatabase db = initializer.getReadableDatabase();
String sql = "SELECT * FROM " + TABLE_NAME + " WHERE " + STATUS + " = '" + BOOKMARKED + "'";
Cursor cursor = db.rawQuery(sql, null);
List<Word> wordList = new ArrayList<Word>();
while(cursor.moveToNext()) {
int id = cursor.getInt(0);
String sanskrit = cursor.getString(1);
String bangla = cursor.getString(2);
String status = cursor.getString(3);
wordList.add(new Word(id, sanskrit, bangla, status));
}
cursor.close();
db.close();
return wordList;
}
public void bookmark(int id) {
SQLiteDatabase db = initializer.getWritableDatabase();
String sql = "UPDATE " + TABLE_NAME + " SET " + STATUS + " = '"
+ BOOKMARKED + "' WHERE " + ID + " = " + id;
db.execSQL(sql);
db.close();
}
public void deleteBookmark(int id) {
SQLiteDatabase db = initializer.getWritableDatabase();
String sql = "UPDATE " + TABLE_NAME + " SET " + STATUS + " = '' " +
" WHERE " + ID + " = " + id;
db.execSQL(sql);
db.close();
}
}
My RecyclerView codes
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>implements Filterable {
private Context context;
private List<Word> wordList;
List<Word> filwordList;
private DictionaryDB dictionaryDB;
public RecyclerViewAdapter(Context context, List<Word> itemList, DictionaryDB dictionaryDB) {
this.context = context;
this.wordList = itemList;
this.dictionaryDB = dictionaryDB;
filwordList = new ArrayList<Word>(itemList);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.wordslist_two_rv, parent, false);
// Create and return a new holder instance
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
final Word word = wordList.get(position);
holder.msanskrit.setText(word.sanskrit);
if(word.status != null && word.status.equals(DictionaryDB.BOOKMARKED)) {
holder.bookmark.setImageResource(R.drawable.cards_heart);
}
else {
holder.bookmark.setImageResource(R.drawable.cards_heart_grey);
}
holder.bookmark.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
bookMarkWord(word, holder.bookmark);
}
});
}
private void bookMarkWord(final Word word, final ImageButton bookmark) {
if (word.status != null && word.status.equals(DictionaryDB.BOOKMARKED)) {
dictionaryDB.deleteBookmark(word.id);
word.status = "";
bookmark.setImageResource(R.drawable.cards_heart_grey);
Toast.makeText(context, "Bookmark Deleted", Toast.LENGTH_SHORT).show();
}
else {
dictionaryDB.bookmark(word.id);
word.status = DictionaryDB.BOOKMARKED;
bookmark.setImageResource(R.drawable.cards_heart);
Toast.makeText(context, "Bookmark Added", Toast.LENGTH_SHORT).show();
}
}
/*
public void updateEntries(List<Word> wordList) {
if (wordList == null) {
AlertDialog dialog = new AlertDialog.Builder(context)
.setTitle("Sorry!")
.setMessage("Your phone doesn't support pre-built database")
.create();
dialog.show();
} else {
this.wordList = wordList;
notifyDataSetChanged();
}
}
*/
#Override
public Filter getFilter() {
return Searched_Filter;
}
private Filter Searched_Filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
List<Word> filteredList = new ArrayList<>();
if (constraint == null || constraint.length() == 0) {
filteredList.addAll(filwordList);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (Word item : filwordList) {
if (item.getSanskrit().toLowerCase().contains(filterPattern)) {
filteredList.add(item);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
wordList.clear();
wordList.addAll((ArrayList<Word>)results.values);
notifyDataSetChanged();
}
};
#Override
public int getItemCount() {
return wordList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView msanskrit;
final ImageButton bookmark;
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
msanskrit = itemView.findViewById(R.id.tvSansTerm);
// mbangla = itemView.findViewById(R.id.tvBnTerm);
bookmark = itemView.findViewById(R.id.bookmarkBtn);
}
#Override
public void onClick(View view) {
int position = this.getAdapterPosition();
Word word = wordList.get(position);
String sanskrit = word.getSanskrit();
String bangla = word.getBangla();
// String sources = term.getMSources();
Intent intent = new Intent(context, TermThreeDetailsActivity.class);
intent.putExtra("Rsanskrit", sanskrit);
intent.putExtra("Rbangla", bangla);
// intent.putExtra("Rsources", sources);
context.startActivity(intent);
}
}
}
My Detalis Fragment codes
public class TermThreeDetailsFragment extends Fragment {
private Toolbar toolbar;
TextView termTextView,descTextView;
private ImageButton imgBtn;
private DictionaryDB dictionaryDB;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.show_three_details, container, false);
termTextView = view.findViewById(R.id.textvWord);
descTextView = view.findViewById(R.id.textvDesc);
imgBtn = view.findViewById(R.id.favAddBtn);
getData();
toolbar = ((Toolbar) view.findViewById(R.id.toolbar));
AppCompatActivity activity = (AppCompatActivity) getActivity();
activity.setSupportActionBar(toolbar);
setHasOptionsMenu(true);
DatabaseInitializer initializer = new DatabaseInitializer(getContext());
initializer.initializeDataBase();
dictionaryDB = new DictionaryDB(initializer);
WordCheck();
return view;
}
public void getData() {
Intent intent = getActivity().getIntent();
String sanskrit = intent.getStringExtra("Rsanskrit");
String bangla = intent.getStringExtra("Rbangla");
termTextView.setText(sanskrit);
descTextView.setText(bangla);
}
private void WordCheck() {
final Word word = new Word();
if(word.status != null && word.status.equals(DictionaryDB.BOOKMARKED)) {
imgBtn.setImageResource(R.drawable.cards_heart);
}
else {
imgBtn.setImageResource(R.drawable.cards_heart_grey);
}
imgBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
bookMarkWord(word, imgBtn);
}
});
}
private void bookMarkWord(final Word word, final ImageButton imgBtn) {
if (word.status != null && word.status.equals(DictionaryDB.BOOKMARKED)) {
dictionaryDB.deleteBookmark(word.id);
word.status = "";
imgBtn.setImageResource(R.drawable.cards_heart_grey);
Toast.makeText(getContext(), "Bookmark Deleted", Toast.LENGTH_SHORT).show();
}
else {
dictionaryDB.bookmark(word.id);
word.status = DictionaryDB.BOOKMARKED;
imgBtn.setImageResource(R.drawable.cards_heart);
Toast.makeText(getContext(), "Bookmark Added", Toast.LENGTH_SHORT).show();
}
}}
My Favorite Fragment codes
public class FavoritesFragment extends Fragment {
RecyclerView rv;
private LinearLayoutManager layoutManager;
DictionaryDB dictionaryDB;
FavoriteAdapter rvFavAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.favorites_fragment,container,false);
Toolbar toolbar = ((Toolbar) view.findViewById(R.id.fav_toolbar));
AppCompatActivity activity = (AppCompatActivity) getActivity();
activity.setSupportActionBar(toolbar);
setHasOptionsMenu(true);
DatabaseInitializer initializer = new DatabaseInitializer(getContext());
initializer.initializeDataBase();
dictionaryDB = new DictionaryDB(initializer);
List<Word> wordList = dictionaryDB.getBookmarkedWords();
rv = ((RecyclerView) view.findViewById(R.id.rvFavorites));
if (wordList.size() != 0) {
layoutManager = new LinearLayoutManager(getContext());
rv.setLayoutManager(layoutManager);
rv.setHasFixedSize(true);
rvFavAdapter = new FavoriteAdapter(getContext(), dictionaryDB,wordList);
rv.setAdapter(rvFavAdapter);
} else {
Toast.makeText(getContext(), "You have no bookmark yet.", Toast.LENGTH_SHORT).show();
}
return view;
}
}
When i use bookmark codes from direct RecyclerView
When i use same bookmark codes from another fragment this happens
Any help will be heavily appreciated 🙏
Problem Solved
Just add those to RecyclerView
int position = this.getAdapterPosition();
Word word = wordList.get(position);
Bundle bundle = new Bundle();
bundle.putParcelable("allData", word);
Fragment detailsFragment = new TermThreeDetailsFragment();
detailsFragment.setArguments(bundle);
FragmentTransaction fT =((AppCompatActivity)context).getSupportFragmentManager().beginTransaction();
fT.replace(R.id.fragment_container, detailsFragment);
fT.addToBackStack(null);
fT.commit();
}
And add this codes to Fragment Class
word = new Word(Parcel.obtain());
Bundle bundle = this.getArguments();
if (bundle != null) {
word = bundle.getParcelable("allData");
termTextView.setText(word.getSanskrit());
descTextView.setText(word.getBangla());
}
*** You need to make you POJO class Parcelable to pass objects between fragments. ***
I get duplicate data items in the RecyclerView when data is retrieved.
I have tried some such like way NotifyDataSetChanged() and setHasStableIds (true). But still has not succeeded and I tried this way (How to solve duplicate data items in recyclerview) but still has not succeededed too.
private void loadFirstPage() {
Log.d(TAG, "loadFirstPage: ");
callTopRatedMoviesApi().enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
if (!response.isSuccessful()) {
Log.e(TAG, "Response Error : " + response.code());
} else {
try {
JSONObject jsonObject = new JSONObject(response.body().toString());
JSONObject dataObject = jsonObject.getJSONObject("data");
JSONArray itemsObject = dataObject.getJSONArray("items");
modelGetProductSearchList = new ArrayList<>();
progressBar.setVisibility(View.GONE);
if (itemsObject.length() == 0) {
// Set GONE Visibility of TextView
} else {
for (int a = 0; a <= itemsObject.length(); a++) {
JSONObject object = itemsObject.getJSONObject(a);
ModelGetProductSearch modelGetProductSearch = new ModelGetProductSearch();
modelGetProductSearch.setId(object.getInt("id"));
modelGetProductSearch.setName(object.getString("name"));
JSONObject sourceObject = object.getJSONObject("source");
modelGetProductSearch.setSourceNames(sourceObject.getString("name"));
modelGetProductSearchList.add(modelGetProductSearch);
adapter.addAll(modelGetProductSearchList);
progressBar.setVisibility(View.GONE);
tvTidakAdaHasil.setVisibility(View.GONE);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
if (currentPage <= TOTAL_PAGES && currentPage <= adapter.getItemCount()) adapter.addLoadingFooter();
else isLastPage = true;
}
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
Log.e(TAG, "onFailure: " + t.getMessage());
tvTidakAdaHasil.setText("Maaf, cek koneksi internet anda dan coba kembali");
progressBar.setVisibility(View.GONE);
}
});
}
private void loadNextPage() {
Log.d(TAG, "loadNextPage: " + currentPage);
callTopRatedMoviesApi().enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
adapter.removeLoadingFooter();
isLoading = false;
if (!response.isSuccessful()) {
Log.e(TAG, "Response Error : " + response.code());
} else {
try {
JSONObject jsonObject = new JSONObject(response.body().toString());
JSONObject dataObject = jsonObject.getJSONObject("data");
JSONArray itemsObject = dataObject.getJSONArray("items");
modelGetProductSearchList = new ArrayList<>();
progressBar.setVisibility(View.GONE);
for (int a = 0; a <= itemsObject.length(); a++) {
JSONObject object = itemsObject.getJSONObject(a);
ModelGetProductSearch modelGetProductSearch = new ModelGetProductSearch();
modelGetProductSearch.setId(object.getInt("id"));
modelGetProductSearch.setName(object.getString("name"));
JSONObject sourceObject = object.getJSONObject("source");
modelGetProductSearch.setSourceNames(sourceObject.getString("name"));
modelGetProductSearchList.add(modelGetProductSearch);
adapter.addAll(modelGetProductSearchList);
progressBar.setVisibility(View.GONE);
}
} catch (JSONException e) {
e.printStackTrace();
}
if (currentPage != TOTAL_PAGES && currentPage <= adapter.getItemCount()) adapter.addLoadingFooter();
else isLastPage = true;
}
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
Log.e(TAG, "onFailure: " + t.getMessage());
tvTidakAdaHasil.setText("Maaf, cek koneksi internet anda dan coba kembali");
progressBar.setVisibility(View.GONE);
}
});
}
and this is my adapter
public class AdapterDetailSearch extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int ITEM = 0;
private static final int LOADING = 1;
private List<ModelGetProductSearch> modelGetProductSearchList;
private Context context;
private boolean isLoadingAdded = false;
public AdapterDetailSearch(Context context) {
this.context = context;
modelGetProductSearchList = new ArrayList<>();
}
public List<ModelGetProductSearch> getMovies() {
return modelGetProductSearchList;
}
public void setMovies(List<ModelGetProductSearch> movieResults) {
this.modelGetProductSearchList = movieResults;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
case ITEM:
viewHolder = getViewHolder(parent, inflater);
break;
case LOADING:
View v2 = inflater.inflate(R.layout.row_item_progress, parent, false);
viewHolder = new LoadingVH(v2);
break;
}
return viewHolder;
}
#NonNull
private RecyclerView.ViewHolder getViewHolder(ViewGroup parent, LayoutInflater inflater) {
RecyclerView.ViewHolder viewHolder;
View viewHolder = inflater.inflate(R.layout.row_item_detail_list, parent, false);
return new MovieVH(viewHolder);
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
final ModelGetProductSearch result = modelGetProductSearchList.get(position);
switch (getItemViewType(position)) {
case ITEM:
final MovieVH itemsListVH = (MovieVH) holder;
// Visible and Invisible set TextView
}
}
#Override
public int getItemCount() {
return modelGetProductSearchList == null ? 0 : modelGetProductSearchList.size();
}
#Override
public int getItemViewType(int position) {
return (position == modelGetProductSearchList.size() - 1 && isLoadingAdded) ? LOADING : ITEM;
}
/*
Helpers
_________________________________________________________________________________________________
*/
public void add(ModelGetProductSearch r) {
modelGetProductSearchList.add(r);
notifyItemInserted(modelGetProductSearchList.size() - 1);
}
public void addAll(List<ModelGetProductSearch> moveResults) {
for (ModelGetProductSearch result : moveResults) {
add(result);
}
}
public void remove(ModelGetProductSearch r) {
int position = modelGetProductSearchList.indexOf(r);
if (position > -1) {
modelGetProductSearchList.remove(position);
notifyItemRemoved(position);
}
}
public void clear() {
isLoadingAdded = false;
while (getItemCount() > 0) {
remove(getItem(0));
}
}
public boolean isEmpty() {
return getItemCount() == 0;
}
public void addLoadingFooter() {
isLoadingAdded = true;
add(new ModelGetProductSearch());
}
public void removeLoadingFooter() {
isLoadingAdded = false;
int position = modelGetProductSearchList.size() - 1;
ModelGetProductSearch result = getItem(position);
if (result != null) {
modelGetProductSearchList.remove(position);
notifyItemRemoved(position);
}
}
public ModelGetProductSearch getItem(int position) {
return modelGetProductSearchList.get(position);
}
/*
View Holders
_________________________________________________________________________________________________
*/
/**
* Main list's content ViewHolder
*/
protected class MovieVH extends RecyclerView.ViewHolder {
private LinearLayout llContainer;
private ImageView ivItem;
private TextView tvItemTitle, tvPriceRegular, tvPriceAfterDiscount, textFrom;
public MovieVH(View itemView) {
super(itemView);
llContainer = itemView.findViewById(R.id.container);
ivItem = itemView.findViewById(R.id.iv_item);
textFrom = itemView.findViewById(R.id.tv_from);
}
}
protected class LoadingVH extends RecyclerView.ViewHolder {
public LoadingVH(View itemView) {
super(itemView);
}
}
}
You add the same list multiple times in your adapter inside for-loop that's why it creates duplication. Move adapter.addAll outside for loop like below:
if (itemsObject.length() == 0) {
// Set GONE Visibility of TextView
} else {
for (int a = 0; a < itemsObject.length(); a++) {
...
//Remove from here
/*adapter.addAll(modelGetProductSearchList);
progressBar.setVisibility(View.GONE);
tvTidakAdaHasil.setVisibility(View.GONE);*/
}
//Add list here
adapter.addAll(modelGetProductSearchList);
progressBar.setVisibility(View.GONE);
tvTidakAdaHasil.setVisibility(View.GONE);
}
I implemented the displaying contacts with checkboxes. When I selected the multiple contacts and click the button it shows this error "
Attempt to invoke virtual method 'boolean
java.lang.Boolean.booleanValue()' on a null object reference"
. at mCustomAdapter.mCheckedStates.get(i). So i wrote like this in adapter class is "
mCheckedStates = new LongSparseArray<>(ContactList.size())
And again it shows the same error after assigning some value. When I print the size of the mCustomAdapter.mCheckedStates.size it show the correct value of how many contacts I selected but when getting the value it shows the error. How to solve that?
This is My adapter class :
public class Splitadapter extends BaseAdapter implements Filterable,CompoundButton.OnCheckedChangeListener
{
// public SparseBooleanArray mCheckStates;
LongSparseArray<Boolean> mCheckedStates = new LongSparseArray<>();
private ArrayList<COntactsModel> ContactList;
private Context mContext;
private LayoutInflater inflater;
private ValueFilter valueFilter;
ArrayList<COntactsModel> ContactListCopy ;
public Splitadapter(Context context, ArrayList<COntactsModel> ContactList) {
super();
mContext = context;
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.ContactList = ContactList;
this.ContactListCopy = this.ContactList;
mCheckedStates = new LongSparseArray<>(ContactList.size());
System.out.println("asdfghjk" + mCheckedStates);
getFilter();
}//End of CustomAdapter constructor
#Override
public int getCount() {
return ContactListCopy.size();
}
#Override
public Object getItem(int position) {
return ContactListCopy.get(position).getName();
}
#Override
public long getItemId(int position) {
return ContactListCopy.get(position).getId();
}
public class ViewHolder {
TextView textviewName;
TextView textviewNumber;
CheckBox checkbox;
Button b;
int id;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
final int pos = position;
//
if (convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(mContext).inflate(R.layout.list, null);
holder.textviewName = (TextView) convertView.findViewById(R.id.name);
holder.textviewNumber = (TextView) convertView.findViewById(R.id.mobile);
holder.checkbox = (CheckBox) convertView.findViewById(R.id.check);
holder.b = convertView.findViewById(R.id.round_icon);
convertView.setTag(holder);
}//End of if condition
else {
holder = (ViewHolder) convertView.getTag();
}//End of else
COntactsModel c = ContactListCopy.get(position);
holder.textviewName.setText(c.getName());
holder.textviewNumber.setText(c.getPhonenum());
holder.checkbox.setTag(c.getId());
holder.checkbox.setChecked(mCheckedStates.get(c.getId(), false));
holder.checkbox.setOnCheckedChangeListener(this);
holder.b.setText(c.getName().substring(0,1));
//holder.id = position;
return convertView;
// }//End of getView method
}
boolean isChecked(long id) {// it returns the checked contacts
return mCheckedStates.get(id, false);
}
void setChecked(long id, boolean isChecked) { //set checkbox postions if it sis checked
mCheckedStates.put(id, isChecked);
System.out.println("hello...........");
notifyDataSetChanged();
}
void toggle(long id) {
setChecked(id, !isChecked(id));
}
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
mCheckedStates.put((Long) buttonView.getTag(), true);
} else {
mCheckedStates.delete((Long) buttonView.getTag());
}
}
#Override
public Filter getFilter() {
if (valueFilter == null) {
valueFilter = new ValueFilter();
}
return valueFilter;
}
private class ValueFilter extends Filter {
//Invoked in a worker thread to filter the data according to the constraint.
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null && constraint.length() > 0) {
ArrayList<COntactsModel> filterList = new ArrayList<COntactsModel>();
for (int i = 0; i < ContactList.size(); i++) {
COntactsModel ca = ContactList.get(i);
if ((ca.getName().toUpperCase())
.contains(constraint.toString().toUpperCase())) {
//COntactsModel contacts = new COntactsModel();
filterList.add(ca);
}
}
results.count = filterList.size();
results.values = filterList;
} else {
results.count = ContactList.size();
results.values = ContactList;
}
return results;
}
//Invoked in the UI thread to publish the filtering results in the user interface.
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
ContactListCopy = (ArrayList<COntactsModel>) results.values;
notifyDataSetChanged();
}
}
}
This my Main Activity :
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
public static String TAG = "amount";
ListView mainListView;
ProgressDialog pd;
public static final int PERMISSIONS_REQUEST_READ_CONTACTS = 100;
final static List<String> name1 = new ArrayList<>();
List<String> phno1 = new ArrayList<>();
List<Long> bal = new ArrayList<>();
List<Bitmap> img = new ArrayList<>();
private Splitadapter mCustomAdapter;
private ArrayList<COntactsModel> _Contacts = new ArrayList<COntactsModel>();
HashSet<String> names = new HashSet<>();
Set<String>phonenumbers = new HashSet<>();
Button select;
int amount=100;
float result;
String ph;
String phoneNumber;
EditText search;
String contactID;
String name;
// private FirebaseAuth mAuth;
// FirebaseUser firebaseUser;
//
// FirebaseFirestore db = FirebaseFirestore.getInstance();
#SuppressLint("StaticFieldLeak")
#Override
protected void onCreate(Bundle savedInstanceState) {
setTitle("Split");
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
search = findViewById(R.id.search_bar);
final List<String> phonenumber = new ArrayList<>();
System.out.print(phonenumber);
mainListView = findViewById(R.id.listview);
showContacts();
select = findViewById(R.id.button1);
search.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user chan ged the Text
mCustomAdapter.getFilter().filter(cs.toString());
//
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
//ma.filter(text);
}
});
select.setOnClickListener(new View.OnClickListener() {
#SuppressLint("NewApi")
#Override
public void onClick(View v) {
StringBuilder checkedcontacts = new StringBuilder();
ArrayList checkedcontacts1 = new ArrayList();
ArrayList names = new ArrayList();
System.out.println(".............." + (mCustomAdapter.mCheckedStates.size()));
System.out.println("name size is" + name1.size());
int a = mCustomAdapter.mCheckedStates.size();
result = ((float) amount / a);
System.out.println("final1 amount is " + result);
long result1 = (long) result;
System.out.println("final amount is " + result1);
for (int k = 0; k < a; k++) {
bal.add(result1);
}
System.out.println("balance" + bal);
System.out.println("selected contacts split amount" + result);
System.out.println("names" + name1.size());
// int as = name1.size();
// mCustomAdapter.mCheckedStates = new LongSparseArray<>(as);
System.out.println("cjgygytygh" + mCustomAdapter.mCheckedStates);
for (int i = 0; i < name1.size(); i++) // it displays selected contacts with amount
{
System.out.println("checked contcts" + mCustomAdapter.mCheckedStates.get(i));
if (mCustomAdapter.mCheckedStates.get(i)) {
checkedcontacts.append(phno1.get(i)).append("\t").append("\t").append("\t").append(result1);
checkedcontacts1.add((phno1.get(i)));
names.add((name1.get(i)));
checkedcontacts.append("\n");
System.out.println("checked contacts:" + "\t" + phno1.get(i) + "\t" + "amount" + "\t" + result1);
}
}
System.out.println("checked names" + names);
System.out.println(
"checkec contcts foggfgfgfgfgf" + checkedcontacts1
);
List<Object> list = new ArrayList<>();
for (Object i : checkedcontacts1) {
list.add(i);
}
System.out.println("checked contacts size is" + checkedcontacts1.size());
HashMap<String, HashMap<String, Object>> Invites = new HashMap<>();
for (int i = 0; i < checkedcontacts1.size(); i++) {
HashMap<String, Object> entry = new HashMap<>();
entry.put("PhoneNumber", list.get(i));
entry.put("Name", names.get(i));
System.out.println("entry is" + entry);
for (int j = i; j <= i; j++) {
System.out.println("phonenumber" + i + ":" + list.get(i));
System.out.println("amount" + j + ":" + bal.get(j));
//dataToSave.put("phonenumber" +i, list.get(i));
entry.put("Amount", bal.get(j));
}
Invites.put("Invite" + i, entry);
}
Intent intent = new Intent(MainActivity.this, Display.class);
intent.putExtra("selected", checkedcontacts1.toString().split(","));
startActivity(intent);
}
});
}
private void showContacts() // it is for to check the build versions of android . if build version is >23 or above it is set the permissions at the run time . if the build version is less than 23 the we give the permissions at manifest file .
{if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, PERMISSIONS_REQUEST_READ_CONTACTS);
}
else {
mCustomAdapter = new Splitadapter(MainActivity.this,_Contacts);
//ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1,aa);
mainListView.setAdapter(mCustomAdapter);
mainListView.setOnItemClickListener(this);
mainListView.setItemsCanFocus(false);
mainListView.setTextFilterEnabled(true);
getAllContacts();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, // it is display the request access permission dilogue box to access the contacts of user.
#NonNull int[] grantResults) {
if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission is granted
showContacts();
} else {
Toast.makeText(this, "Until you grant the permission, we canot display the names", Toast.LENGTH_SHORT).show();
}
}
}
private void getAllContacts() {
// it displays the contact phonenumber and name rom the phone book. and add to the list.
ContentResolver cr = getContentResolver();
String[] PROJECTION = new String[] {
ContactsContract.RawContacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.PHOTO_URI,
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER,
ContactsContract.CommonDataKinds.Photo.CONTACT_ID };
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String filter = ""+ ContactsContract.Contacts.HAS_PHONE_NUMBER + " > 0 and " + ContactsContract.CommonDataKinds.Phone.TYPE +"=" + ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE;
String order = ContactsContract.Contacts.DISPLAY_NAME + " ASC";
Cursor phones = cr.query(uri, PROJECTION, filter, null, order);
while (phones.moveToNext()) {
long id = phones.getLong(phones.getColumnIndex(ContactsContract.Data._ID));
name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
_Contacts.add(new COntactsModel(id,name,phoneNumber));
name1.add(name);
phno1.add(phoneNumber);
}
phones.close();
}
public static Bitmap loadContactPhoto(ContentResolver cr, long id) {
Uri uri = ContentUris.withAppendedId(
ContactsContract.Contacts.CONTENT_URI, id);
InputStream input = ContactsContract.Contacts
.openContactPhotoInputStream(cr, uri);
if (input == null) {
return null;
}
return BitmapFactory.decodeStream(input);
}
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
mCustomAdapter.toggle(arg3);
}
This my Model Class :
public class COntactsModel
{
String phonenum;
long id;
String cname;
boolean selected = false;
public COntactsModel(long id, String name,String phonenumber) {
this.id = id;
this.cname = name;
this.phonenum = phonenumber;
}
public long getId() {
return this.id;
}
public String getName() {
return this.cname;
}
public String getPhonenum() {
return this.phonenum;
}
}
How to solve that error?
I'm facing an odd situation here, when I search for an item it returns me what I'm searching for, but it is doing something else too, it is adding 2 empty rows to the listview by each character pressed on the search, if I search for example: "fire" it will add 8 empty rows at the end of my listview, why is this happening?
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class FragmentClientes extends Fragment implements OnQueryTextListener{
private boolean searchCheck;
private List<ClienteModel> clientes = new ArrayList<ClienteModel>();
private ListView lv;
private View rootView;
ProgressBar progressBar;
private LinearLayout footerLinearLayout;
public FragmentActivity activity;
private SearchView searchView;
private String currentQuery = null;
private ClientViewAdapter ad;
private ClientSearchViewAdapter ads;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
rootView = inflater.inflate(R.layout._fragment_clientes, container, false);
rootView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT ));
return rootView;
}
public void gerarToast(CharSequence message) {
int duration = Toast.LENGTH_LONG;
Toast toast = Toast
.makeText(getActivity(), message, duration);
toast.show();
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// TODO Auto-generated method stub
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu, menu);
searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(Menus.PROCURAR));
if (searchView != null) {
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
public boolean onQueryTextSubmit(String submit) {
// showResults(submit, 1);
return false;
}
public boolean onQueryTextChange(String change) {
//TODO Auto-generated method stub
if (searchCheck) {
showResults();
try {
clientes = new ArrayList<ClienteModel>();
Repositorio mRepositorio = new Repositorio(getActivity());
List Clientes = mRepositorio.getClientes(change, 15, 1);
clientes = Clientes;
ads = new ClientSearchViewAdapter(getActivity(), this, clientes);
lv.addFooterView(footerLinearLayout);
lv.setOnScrollListener(new EndlessScrollListener() {
#Override
public void onLoadMore(int page, int totalItemsCount) {
new LoadMoreClientTask(progressBar, FragmentClientes.this, ad, getActivity()).execute(1);
System.out.println("PAGE " + page);
}
});
new LoadMoreClientTask(progressBar, this, ad, getActivity()).execute(1);
lv.setAdapter(ads);
System.out.println("Pesquisa: " + clientes);
}catch (Exception e){
e.printStackTrace();
}
}
return false;
}
});
}
searchView.setQueryHint(this.getString(R.string.search));
((EditText)searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text))
.setHintTextColor(getResources().getColor(R.color.white));
menu.findItem(Menus.PROCURAR).setVisible(true);
searchCheck = true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case Menus.PROCURAR:
searchCheck = true;
break;
}
return true;
}
private void showResults() {
try {
progressBar = new ProgressBar(getActivity(), null, android.R.attr.progressBarStyle);
LinearLayout.LayoutParams progressBarParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
progressBar.setLayoutParams(progressBarParams);
progressBar.setPadding(6, 6, 6, 6);
footerLinearLayout = new LinearLayout(getActivity());
AbsListView.LayoutParams layoutParams = new AbsListView.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
footerLinearLayout.setGravity(Gravity.CENTER);
footerLinearLayout.setLayoutParams(layoutParams);
footerLinearLayout.addView(progressBar);
lv = (ListView) rootView.findViewById(R.id.listaClientes);
clientes = new ArrayList<ClienteModel>();
ad = new ClientViewAdapter(getActivity(), this, clientes);
lv.setVerticalFadingEdgeEnabled(true);
lv.setVerticalScrollBarEnabled(true);
lv.setAdapter(ad);
} catch (Exception e) {
e.printStackTrace();
}
}
LoadMoreTask:
public class LoadMoreClientTask extends AsyncTask<Integer, Void, Boolean> {
private SearchView.OnQueryTextListener activity;
private ClientViewAdapter adapter;
private List<ClienteModel> cliente = new ArrayList<ClienteModel>();
private ProgressBar progressBar;
private Context context;
public LoadMoreClientTask(ProgressBar progressBar, SearchView.OnQueryTextListener activity, ClientViewAdapter adapter, Context context){
this.progressBar = progressBar;
this.activity = activity;
this.adapter = adapter;
this.context = context;
}
#Override
protected void onPreExecute() {
progressBar.setVisibility(View.VISIBLE);
}
#Override
protected Boolean doInBackground(Integer... parameters) {
int npagina = parameters[0];
cliente= new ArrayList<ClienteModel>();
try {
Repositorio mRepositorio = new Repositorio(context);
List listaDeClientes = mRepositorio.getClientes("", 5, npagina);
cliente = listaDeClientes;
System.out.println("pagina " + npagina);
}catch (Exception e){
e.printStackTrace();
return false;
}
return true;
}
#Override
protected void onPostExecute(Boolean result) {
if(result){
adapter.setData(cliente);
}
progressBar.setVisibility(View.INVISIBLE);
}
}
getClientes:
public List<ClienteModel> getClientes( String consulta, Integer limit, Integer pagina) throws SQLException {
int offset = pagina * limit - limit;
System.out.println("OFFSET: "+ offset);
List<ClienteModel> listaDeRegistros = new ArrayList<ClienteModel>();
System.out.println("Consulta: "+ consulta);
if(consulta.isEmpty()) {
query = "SELECT * FROM " + tabelaCLIENTES + " WHERE credencial_id = " + mSessao.getString("id_credencial") + " LIMIT " + offset + ", " + limit;
}else {
query = "SELECT * FROM " + tabelaCLIENTES + " WHERE (credencial_id = " + mSessao.getString("id_credencial") + ") AND (nome LIKE '%"+consulta+"%') LIMIT " + offset + ", " + limit;
}
System.out.println(query);
try {
Cursor mCursor = bd.rawQuery(query, null);
if (mCursor.getCount() > 0) {
if (mCursor.moveToFirst()) {
do {
ClienteModel mClienteModel = new ClienteModel();
mClienteModel.setClientes_id(mCursor.getInt(mCursor.getColumnIndex(ClienteModel.Coluna.CLIENTES_ID)));
mClienteModel.setId_rm(mCursor.getInt(mCursor.getColumnIndex(ClienteModel.Coluna.ID_RM)));
mClienteModel.setCredencial_id(mCursor.getInt(mCursor.getColumnIndex(ClienteModel.Coluna.CREDENCIAL_ID)));
mClienteModel.setNome(mCursor.getString(mCursor.getColumnIndex(ClienteModel.Coluna.NOME)));
mClienteModel.setTipo(mCursor.getString(mCursor.getColumnIndex(ClienteModel.Coluna.TIPO)));
mClienteModel.setInformacao_adicional(mCursor.getString(mCursor.getColumnIndex(ClienteModel.Coluna.INFORMACAO_ADICIONAL)));
mClienteModel.set_criado(mCursor.getString(mCursor.getColumnIndex(ClienteModel.Coluna._CRIADO)));
mClienteModel.set_modificado(mCursor.getString(mCursor.getColumnIndex(ClienteModel.Coluna._MODIFICADO)));
mClienteModel.set_status(mCursor.getString(mCursor.getColumnIndex(ClienteModel.Coluna._STATUS)));
listaDeRegistros.add(mClienteModel);
} while (mCursor.moveToNext());
}
}
} catch (Exception e) {
e.printStackTrace();
}
return listaDeRegistros;
}
It's doing this because you keep adding the footerView for the query changes.
lv.addFooterView(footerLinearLayout);
You should add the footerView one time and keep a reference to it in the Activity and then update the view as needed.