I have a RecyclerView and each row has a EditText also. I am adding item to RecyclerView by searching them and then I type the quantity in the edit text. Then I send it to the server to store using json format. Item add is working perfectly. There is no edit text value swapping problem also when scrolling. I can display 5 rows in the screen.
Problem is when I send item to the server, edit text values in bottom rows get the same after 5th row.
These are the rows I am adding to the recyclerview.Printed List that send to the server.
Item : 7.50-15 10PR FM CEAT Quantity : 1
Item : 5.60-15 04PR K 511 CEAT Quantity : 2
Item : 2.75-18 04PR SECURA F85 CEAT (F) Quantity : 3
Item : 3.00-17 06PR SECURA ZOOM CEAT (R) Quantity : 4
Item : 6.50-14 10PR FM CEAT Quantity : 5
Item : 5.00-12 04PR GRIP MASTER CEAT Quantity : 5
Item : 4.00-08 06PR AUTO RAJA RPG Quantity : 5
Item : 9.00-20 14PR CEAT CLT LUG Quantity : 5
Item : 8.25-20 14PR TR PLUS SUNTRAC Quantity : 5
Item : 7.00-15 12PR FM CEAT Quantity : 5
After the 5th position Quantity is the same. My input value is not coming.
This is my SelectItem class -
public class SelectItem extends AppCompatActivity implements SelectItemAdapter.OnItemClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.select_item);
vollySingleton = VollySingleton.getsInstance();
requestQueue = vollySingleton.getmRequestQueue();
toolbar = (Toolbar) findViewById(R.id.app_bar);
setSupportActionBar(toolbar);
getSupportActionBar().setHomeButtonEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
myRecyclerView = (RecyclerView) findViewById(R.id.selectedItemRecyclerView);
linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
spinner = (Spinner) findViewById(R.id.selectDistribChannel);
arrayAdapter = new ArrayAdapter<String>(this, R.layout.spinner_item, YourDealerListFragment.disChannel);
arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(arrayAdapter);
selectedDisChannel = spinner.getSelectedItem().toString();
sqLiteHandler = new SQLiteHandler(getApplicationContext());
myRecyclerViewAdapter = new SelectItemAdapter(this);
myRecyclerViewAdapter.setOnItemClickListener(this);
myRecyclerView.setAdapter(myRecyclerViewAdapter);
myRecyclerView.setLayoutManager(linearLayoutManager);
myRecyclerViewAdapter.notifyDataSetChanged();
dealerName = DealerListAdapter.getDealerName();
dealerID = DealerListAdapter.getDealerID();
repID = DealerListAdapter.getRepID();
//order number
orderId = "70000001";
if (newOrderId == null) {
newOrderId = orderId;
}
bAdd = (Button) findViewById(R.id.bAdd);
bAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (myRecyclerViewAdapter.getItemCount() != 0) {
new AlertDialog.Builder(SelectItem.this)
.setTitle("Confirmation")
.setMessage("Do you want to send?")
.setIcon(android.R.drawable.ic_dialog_alert)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
checkOrderNo();
}
})
.setNegativeButton(android.R.string.no, null).show();
} else {
Toast.makeText(getApplicationContext(), "Empty List", Toast.LENGTH_SHORT).show();
}
}
});
//textView.setText(dealerName);
getSupportActionBar().setTitle(dealerName);
final AutoCompleteTextView acTextView = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);
adapter = new MaterialSuggestionAdapter(getApplicationContext());
acTextView.setAdapter(adapter);
acTextView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Product result = adapter.getItem(position);
String newName = result.getMatName().toString();
String newQty = String.valueOf(result.getMatQuantity());
String newPCode = result.getMatNo().toString();
String newPlant = result.getMatPlant().toString();
if (!newName.equals("")) {
if (myRecyclerViewAdapter.getItemCount() > 0) {
if (!isPresent(newPlant, newPCode, myRecyclerViewAdapter)) {
myRecyclerViewAdapter.add(1, newName, newQty, newPCode, newPlant);
} else {
Toast.makeText(getApplicationContext(), "Product Already in the List", Toast.LENGTH_SHORT).show();
}
} else {
myRecyclerViewAdapter.add(0, newName, newQty, newPCode, newPlant);
}
} else {
Toast.makeText(getApplicationContext(), "Invalied Item!", Toast.LENGTH_SHORT).show();
}
acTextView.setText("");
}
});
}
private boolean isPresent(String newPlant, String newPCode, SelectItemAdapter myRecyclerViewAdapter) {
boolean isPresent = false;
for (int i = 0; i < myRecyclerViewAdapter.getItemCount(); i++) {
if (newPCode.equalsIgnoreCase(myRecyclerViewAdapter.getItemPCode(i).toString()) && newPlant.equalsIgnoreCase(myRecyclerViewAdapter.getItemPlant(i).toString())) {
isPresent = true;
break;
}
}
return isPresent;
}
//send items for one order
private class SendItemAsync extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
}
#Override
protected Void doInBackground(Void... arg0) {
//Create JSON string start
json_string = "{\"sending_items\":[";
for (int i = 0; i < myRecyclerViewAdapter.getItemCount(); i++) {
/* if (myRecyclerView.findViewHolderForLayoutPosition(i) instanceof SelectItemAdapter.ItemHolder) {
SelectItemAdapter.ItemHolder childHolder = (SelectItemAdapter.ItemHolder) myRecyclerView.findViewHolderForLayoutPosition(i);
numberPickerNumber = childHolder.getQtyNumber();
}*/
getNumPicNumber(i);
//Repeat and loop this until all objects are added (and add try+catch)
try {
JSONObject obj_new = new JSONObject();
obj_new.put("order_no", orderIdForItemTable);
obj_new.put("items", myRecyclerViewAdapter.getItemName(i).toString());
obj_new.put("items_no", myRecyclerViewAdapter.getItemPCode(i).toString());
obj_new.put("plant", myRecyclerViewAdapter.getItemPlant(i).toString());
obj_new.put("quantity", numberPickerNumber);
json_string = json_string + obj_new.toString() + ",";
} catch (JSONException e) {
e.printStackTrace();
}
}
//Close JSON string
json_string = json_string.substring(0, json_string.length() - 1);
json_string += "]}";
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 3500);
HttpConnectionParams.setSoTimeout(httpParams, 1000);
HttpClient client = new DefaultHttpClient(httpParams);
String url = AppConfig.URL_ITEMS_SEND;
HttpPost request = new HttpPost(url);
try {
request.setEntity(new ByteArrayEntity(json_string.getBytes("UTF8")));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
request.setHeader("json", json_string);
request.setHeader("Accept", "application/json");
request.setHeader("Content-Type", "application/json");
Log.i("", "excuting request");
HttpResponse response = null;
try {
response = client.execute(request);
Log.d("HTTP Response", response.getStatusLine().toString());
try {
String responseBody = EntityUtils.toString(response.getEntity());
Log.d("Server Response", responseBody);
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
finish();
Bundle basket = new Bundle();
basket.putString("dealerName", dealerName);
basket.putString("orderNo", newOrderId);
basket.putString("jsonString", json_string);
Intent intent = new Intent(SelectItem.this, ItemCart.class);
intent.putExtras(basket);
startActivity(intent);
finish();
//Toast.makeText(getApplicationContext(), json_string, Toast.LENGTH_LONG).show();
}
}
private String getNumPicNumber(int i) {
if (myRecyclerView.findViewHolderForLayoutPosition(i) instanceof SelectItemAdapter.ItemHolder) {
SelectItemAdapter.ItemHolder childHolder = (SelectItemAdapter.ItemHolder) myRecyclerView.findViewHolderForLayoutPosition(i);
numberPickerNumber = childHolder.getQtyNumber();
}
return numberPickerNumber;
}
#Override
public void onItemClick(SelectItemAdapter.ItemHolder item, int position) {
Toast.makeText(this,
"Remove " + position + " : " + item.getItemName(),
Toast.LENGTH_SHORT).show();
myRecyclerViewAdapter.remove(position);
}
private void checkOrderNo() {
showDialog();
DateFormat df = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
final String nowDate = df.format(new Date());
//final day of the month
Date today = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(today);
calendar.add(Calendar.MONTH, 1);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.add(Calendar.DATE, -1);
Date lastDayOfMonth = calendar.getTime();
DateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
final String lastDate = sdf.format(lastDayOfMonth);
Log.d("Last day ", sdf.format(lastDayOfMonth) + " // Today" + nowDate);
// Tag used to cancel the insert
String tag_string_req = "req_insert";
final StringRequest strReq = new StringRequest(Request.Method.POST,
AppConfig.URL_ITEM_DETAILS_SEND, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
hideDialog();
try {
JSONObject jObj = new JSONObject(response);
if (jObj.names().get(0).equals("found")) {
newOrderId = jObj.getString("found").toString();
orderIdForItemTable = newOrderId;
new SendItemAsync().execute();
Log.d(TAG, "newOrderId: " + newOrderId);
Log.d(TAG, "New repID 2 inserted into sqlite: " + newOrderId + " " + nowDate);
sqLiteHandler.addItemDetails(newOrderId, repID, dealerID, nowDate, lastDate, selectedDisChannel);
} else {
Toast.makeText(getApplicationContext(), "Invalied Request", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Inserting Error: " + error.getMessage());
Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show();
}
}) {
#Override
protected Map<String, String> getParams() {
// Posting params to register url
Map<String, String> params = new HashMap<String, String>();
params.put("order_no", orderId);
params.put("repID", repID);
params.put("dealerID", dealerID);
params.put("nowDate", nowDate);
params.put("lastDate", lastDate);
params.put("disChannel", selectedDisChannel);
return params;
}
};
strReq.setRetryPolicy(new DefaultRetryPolicy(6000, 1,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
// Adding request to request queue
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
}
}
My Adapter class.
public class SelectItemAdapter extends RecyclerView.Adapter<SelectItemAdapter.ItemHolder> {
private List<String> itemsName, itemsQty, itemsPCode, itemPlant;
private OnItemClickListener onItemClickListener;
private LayoutInflater layoutInflater;
private RecyclerView myRecyclerview;
public SelectItemAdapter(Context context) {
layoutInflater = LayoutInflater.from(context);
itemsName = new ArrayList<String>();
itemsQty = new ArrayList<String>();
itemsPCode = new ArrayList<String>();
itemPlant = new ArrayList<String>();
}
#Override
public SelectItemAdapter.ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = layoutInflater.inflate(R.layout.custom_row_selected_item, parent, false);
return new ItemHolder(itemView, this);
}
#Override
public void onBindViewHolder(SelectItemAdapter.ItemHolder holder, int position) {
holder.setItemName(itemsName.get(position));
holder.setItemQty(itemsQty.get(position));
holder.setItemPCode(itemsPCode.get(position));
holder.setItemPlant(itemPlant.get(position));
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public int getItemCount() {
return itemsName.size();
}
public Object getItemName(int position) {
return itemsName.get(position);
}
public Object getItemPCode(int position) {
return itemsPCode.get(position);
}
public Object getItemPlant(int position) {
return itemPlant.get(position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
onItemClickListener = listener;
}
public OnItemClickListener getOnItemClickListener() {
return onItemClickListener;
}
public interface OnItemClickListener {
public void onItemClick(ItemHolder item, int position);
}
public void add(int location, String iName, String iQty, String iPCode, String iPlant) {
itemsName.add(location, iName);
itemsQty.add(location, iQty);
itemsPCode.add(location, iPCode);
itemPlant.add(location, iPlant);
notifyItemInserted(location);
}
public void remove(int location) {
if (location >= itemsName.size())
return;
itemsName.remove(location);
notifyItemRemoved(location);
}
public static class ItemHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private SelectItemAdapter parent;
TextView textItemName, txtPCode, txtAvailableQty, txtTempQty, txtPlant;
Button bRemove;
EditText numPicker;
public ItemHolder(View itemView, SelectItemAdapter parent) {
super(itemView);
this.parent = parent;
textItemName = (TextView) itemView.findViewById(R.id.txtProductName);
txtAvailableQty = (TextView) itemView.findViewById(R.id.txtAvailbleQty);
txtPCode = (TextView) itemView.findViewById(R.id.txtPCode);
txtPlant = (TextView) itemView.findViewById(R.id.txtPlant);
bRemove = (Button) itemView.findViewById(R.id.bRemove);
numPicker = (EditText) itemView.findViewById(R.id.numberPicker);
bRemove.setOnClickListener(this);
}
public void setItemName(CharSequence name) {
textItemName.setText(name);
}
public void setItemQty(CharSequence name) {
txtAvailableQty.setText(name);
}
public void setItemPCode(CharSequence name) {
txtPCode.setText(name);
}
public void setItemPlant(CharSequence name) {
txtPlant.setText(name);
}
public String getQtyNumber() {
return numPicker.getText().toString();
}
public CharSequence getItemName() {
return textItemName.getText();
}
public CharSequence getItemPCode() {
return txtPCode.getText();
}
#Override
public void onClick(View v) {
final OnItemClickListener listener = parent.getOnItemClickListener();
if (listener != null) {
listener.onItemClick(this, getPosition());
}
}
}
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position, #NonNull List<Object> payloads) {
super.onBindViewHolder(holder, position, payloads);
holder.setIsRecyclable(false);// set this in your adapter class as like it is
}
Override getItemViewType method
override fun getItemViewType(position: Int): Int {
return position
}
RecyclerView creates only as many view holders as are needed to display the on-screen portion of the dynamic content, plus a few extra. As the user scrolls through the list, the RecyclerView takes the off-screen views and rebinds them to the data which is scrolling onto the screen
// Items for recycler View
//binding data
private ArrayList<Data> Items;
//HashMap to store editText text afterTextChanged
//each editext in RecyclerView contains Unique Key And Value
private HashMap<String,String> sourceData=new HashMap<>();
Refer This RecyclerView Program
public class DataRecyclerView extends RecyclerView.Adapter<DataRecyclerView.DataViewHolder> {
private Context context;
// Items for recycler View
//binding data
private ArrayList<Data> Items;
private LayoutInflater layoutInflater;
//HashMap to store editText text afterTextChanged
//each editext in RecyclerView contains Unique Key And Value
private HashMap<String,String> sourceData=new HashMap<>();
DataRecyclerView(Context context,ArrayList<Data> Items)
{
this.Items=Items;
this.context=context;
layoutInflater=LayoutInflater.from(context);
}
#NonNull
#Override
public DataViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//DataBinding is used to bind Data
DataViewHolderBinding binding= DataBindingUtil.inflate(layoutInflater, R.layout.template,parent,false);
return new DataViewHolder(binding);
}
#Override
public void onBindViewHolder(#NonNull DataViewHolder holder, int position) {
//Pass Data pojo to Holder
holder.bindData(Items.get(position));
}
#Override
public int getItemCount() {
return Items.size();
}
class DataViewHolder extends RecyclerView.ViewHolder {
private EditText amount;
DataViewHolder(DataViewHolderBinding itemView) {
super(itemView.getRoot());
binding=itemView;
amount=binding.PayAmount;
}
void bindData(Data data)//Data pojo for DataBinding
{
if(binding!=null) {
// data will automatically set to textViews In DataBinding
binding.setData(data);
//every time data binds to views
//get text of respective edittext and assign to that current edittext
if (sourceData.containsKey((String.valueOf(getAdapterPosition())))) {// checks current editText key is availible or not
if (data.getIDNumber().equals(Items.get(getAdapterPosition()).getData.getIDNumber())) { //
amount.setText(sourceData.get((String.valueOf(getAdapterPosition()))).getAmount());
}else
{
if (data.getIDNumber().equals(Items.get(getAdapterPosition()).getData.getIDNumber())) { //
amount.setText(null);
}
amount.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) {
}
#Override
public void afterTextChanged(Editable s) {
//when user enter text into edittext
//editetext key already availible in sourceData
// then update the value to hashmap sourceData
if (sourceData.containsKey(String.valueOf(getAdapterPosition()))) {
if (data.getIDNumber().equals(Items.get(getAdapterPosition()).getData.getIDNumber())) { //
if (!s.toString().trim().isEmpty()) {
if (!s.toString().trim().equals("0")) {
sourceData.put(String.valueOf(getAdapterPosition()),s.toString().trim());
} else {
sourceData.put(String.valueOf(getAdapterPosition()), s.toString().trim();
}
} else {
sourceData.put(String.valueOf(getAdapterPosition()),null );
}
}
}
else {
//when user enter text into edittext for the first time
//check for current Data pojo IDNumber with getAdapterPosition Items Data pojo IDNumber
//if it equal
//then we store text into hashmap for specific edittext by using adapterPosition as key
if (data.getIDNumber().equals(Items.get(getAdapterPosition()).getData.getIDNumber())) { //
if (!s.toString().trim().isEmpty()) {
if (!s.toString().trim().equals("0")) {
sourceData.put(String.valueOf(getAdapterPosition()),s.toString().trim());
} else {
sourceData.put(String.valueOf(getAdapterPosition()), s.toString().trim();
}
} else {
sourceData.put(String.valueOf(getAdapterPosition()),null );
}
}
}
}
});
}
}
}
}
### Image Reference I can't show proper Image but Its Look Like this
The rows in RecyclerView is reusing while scrolling. So you need to create an array for save each EditText value
Then addTextChangedListener to your EditText to save the EditText value while you input
public void onBindViewHolder(SelectItemAdapter.ItemHolder holder, int position) {
...
holder.numPicker.setText(arrayForSaveEditTextValue[position]);
holder.numPicker.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
#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
arrayForSaveEditTextValue[position] = arg0.toString();
}
});
...
}
Related
I have a RecyclerView of questions (which are saved and retrieved from database) and seekbars (which I save in database).
Link to image
After clicking on SUBMIT EXTRA QUESTIONS there is a dialog which appears
Link to image
I want after clicking on Okay the progress of ALL seekbars to be 0.
I tried to do this submitExpenseData(jsonArrayQuestion.toString(), getId, jsonArrayAnswer.toString(), formatter.format(date));
holder.seekBar.setProgress(0);
But It changes only the progress of the last seekbar. Does anyone have any idea?
public class ExtraQuestionAdapter extends RecyclerView.Adapter<ExtraQuestionAdapter.ExtraQuestionViewHolder> {
private Context mCntx;
private List<ExtraQuestion> extraQuestionList;
private OnExtraAnswerListener onExtraAnswerListener;
private Button btn_submit_extra_questions;
private View rootView;
ArrayList<Integer> answersArray;
private Integer[] array = {};
String getId;
SessionManager sessionManager;
private Dialog dialog;
public ExtraQuestionAdapter(Context mCntx, List<ExtraQuestion> extraQuestionList, OnExtraAnswerListener onExtraAnswerListener) {
this.mCntx = mCntx;
this.extraQuestionList = extraQuestionList;
this.onExtraAnswerListener = onExtraAnswerListener;
}
#NonNull
#Override
public ExtraQuestionViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mCntx);
View view = inflater.inflate(R.layout.extra_question_layout, parent, false);
sessionManager = new SessionManager(mCntx);
HashMap<String, String> user = sessionManager.getUserDetail();
mCntx = parent.getContext();
rootView = ((Activity) mCntx).getWindow().getDecorView().findViewById(android.R.id.content);
//set the size of the array with answers to be equal to the size of the array with questions
array = new Integer[extraQuestionList.size()];
//initialise the array with answers with 0
for (int i = 0; i < extraQuestionList.size(); i++) {
array[i] = 0;
}
getId = user.get(sessionManager.ID);
btn_submit_extra_questions = rootView.findViewById(R.id.btn_submit_extra_questions);
ExtraQuestionViewHolder extraQuestionViewHolder = new ExtraQuestionViewHolder(view, onExtraAnswerListener);
return extraQuestionViewHolder;
}
#Override
public void onBindViewHolder(#NonNull ExtraQuestionViewHolder holder, int position) {
ExtraQuestion extraQuestion = extraQuestionList.get(position);
holder.title.setText(extraQuestion.getExtra_question());
holder.seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
array[holder.getAdapterPosition()] = seekBar.getProgress();
}
});
btn_submit_extra_questions.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dialog = new Dialog(mCntx);
dialog.setContentView(R.layout.dialog_submit);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
dialog.getWindow().setBackgroundDrawable(mCntx.getDrawable(R.drawable.dialog_background));
}
dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
dialog.setCancelable(true);
Button finalSubmit = dialog.findViewById(R.id.btn_submit);
Button cancelSubmit = dialog.findViewById(R.id.btn_cancel);
ImageView info = dialog.findViewById(R.id.info);
TextView termsConditions = dialog.findViewById(R.id.textView3);
// Cancel button in the dialog
cancelSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
//Okay button in the dialog
finalSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//fill the arraylist of answers with the array of answers
answersArray = new ArrayList<>(Arrays.asList(array));
ArrayList<Integer> FAnswerArray = new ArrayList<>();
ArrayList<Integer> FQuestionArray = new ArrayList<>();
if (!answersArray.isEmpty()) {
for (int i = 0; i < answersArray.size(); i++) {
FAnswerArray.add(answersArray.get(i));
FQuestionArray.add(i + 1);
}
}
JSONArray jsonArrayQuestion = new JSONArray();
for (Integer question : FQuestionArray) {
jsonArrayQuestion.put(question);
}
JSONArray jsonArrayAnswer = new JSONArray();
for (Integer answer : FAnswerArray) {
jsonArrayAnswer.put(answer);
}
dialog.dismiss();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date date = new Date(System.currentTimeMillis());
submitExpenseData(jsonArrayQuestion.toString(), getId, jsonArrayAnswer.toString(), formatter.format(date));
}
});
//Info button in the dialog
info.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(mCntx.getApplicationContext(), TermsConditionsActivity.class);
mCntx.startActivity(intent);
}
});
//Terms and conditions in the dialog
termsConditions.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(mCntx.getApplicationContext(), TermsConditionsActivity.class);
mCntx.startActivity(intent);
}
});
dialog.show();
}
});
}
private void submitExpenseData(String extra_questions_id, String users_id, String extra_answer, String timeStamp_date) {
StringRequest stringRequest = new StringRequest(Request.Method.POST, URLs.EXTRA_ANSWERS_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//we get the successful in String response
Log.e("response", response);
try {
JSONObject jsonObject = new JSONObject(response.substring(response.indexOf("{"), response.lastIndexOf("}") + 1));
String success = jsonObject.getString("success");
if (success.equals("1")) {
sessionManager.saveAnswersOfTheDay(extra_questions_id, users_id, extra_answer, timeStamp_date);
Toast.makeText(mCntx.getApplicationContext(), R.string.successQuestionsOfTheDay, Toast.LENGTH_SHORT).show();
}
if (success.equals("alreadySubmitted")) {
Toast.makeText(mCntx.getApplicationContext(), R.string.submit_extra_questions_once_a_day, Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(mCntx.getApplicationContext(), "Error! " + e.toString(), Toast.LENGTH_SHORT).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("sellresponseerror", "" + error.toString());
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("extra_questions_id", extra_questions_id);
params.put("users_id", users_id);
params.put("extra_answer", extra_answer);
params.put("timeStamp_date", timeStamp_date);
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(mCntx);
requestQueue.add(stringRequest);
}
#Override
public int getItemCount() {
return extraQuestionList.size();
}
public class ExtraQuestionViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView title;
SeekBar seekBar;
OnExtraAnswerListener onExtraAnswerListener;
public ExtraQuestionViewHolder(#NonNull View itemView, OnExtraAnswerListener onExtraAnswerListener) {
super(itemView);
title = itemView.findViewById(R.id.textViewTitle);
seekBar = itemView.findViewById(R.id.seekBar);
this.onExtraAnswerListener = onExtraAnswerListener;
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
onExtraAnswerListener.onExtraAnswerClick(getAdapterPosition());
}
}
public interface OnExtraAnswerListener {
void onExtraAnswerClick(int position);
}
}
When I filter my list and click on an item in listview it gives the wrong item information.
Suppose my list contains X, Y, Z. And when I search the list for things starting with Y, I will get Y, but when I click Y, it returns me X or any random item data.
My main activity:
public class exit_Activity extends AppCompatActivity {
String Show_url = "https://retrieve.php";
ListView removeView;
MyAdapter adapter;
public static ArrayList<Employee> employeeArrayList = new ArrayList<>();
Employee employee;
ProgressBar progressBar;
private SwipeRefreshLayout mSwipeRefreshLayout;
public static ArrayList<Employee> filterList = new ArrayList<>();
EditText search;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_exit_);
retrieveData();
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
///
mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.refreshlayout);
mSwipeRefreshLayout.setColorSchemeResources(R.color.black, R.color.green, R.color.red);
mSwipeRefreshLayout.setProgressBackgroundColorSchemeColor(getResources().getColor(R.color.main_blue));
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
mSwipeRefreshLayout.setRefreshing(true);
Toast.makeText(getApplicationContext(), "Updating..", Toast.LENGTH_SHORT).show();
retrieveData();
// do nothing
}
});
progressBar = (ProgressBar) findViewById(R.id.progressbar);
Sprite FoldingCube = new Wave();
progressBar.setIndeterminateDrawable(FoldingCube);
//time and date
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
exit_time();
removeView.requestLayout();
handler.postDelayed(this, 500);
}
}, 500);
//
//
//exit
removeView = findViewById(R.id.exit_entry);
adapter = new MyAdapter(this, employeeArrayList);
removeView.setAdapter(adapter);
//end
removeView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ProgressDialog progressDialog = new ProgressDialog(view.getContext());
startActivity(new Intent(getApplicationContext(), Edit_Activity.class)
.putExtra("id", id));
finish();
}
});
//searchView
search = findViewById(R.id.search);
search.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) {
}
#Override
public void afterTextChanged(Editable s) {
filterList.clear();
if (s.toString().isEmpty()) {
removeView.setAdapter(new MyAdapter(getApplicationContext(), employeeArrayList));
adapter.notifyDataSetChanged();
} else {
Filter(s.toString());
}
}
});
//end
}
public void retrieveData() {
StringRequest request = new StringRequest(Request.Method.POST, Show_url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
employeeArrayList.clear();
try {
JSONObject jsonObject = new JSONObject(response);
String sucess = jsonObject.getString("success");
JSONArray jsonArray = jsonObject.getJSONArray("veeta_vehicles");
if (sucess.equals("1")) {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject object = jsonArray.getJSONObject(i);
String id = object.getString("id");
String number = object.getString("number");
String name = object.getString("name");
String time = object.getString("surnam");
String date = object.getString("dob");
String time = object.getString("die");
String yes = object.getString("yes");
employee = new Employee(id, number, name, time, date, time, yes);
employeeArrayList.add(employee);
adapter.notifyDataSetChanged();
}
progressBar.setVisibility(View.GONE);
mSwipeRefreshLayout.setRefreshing(false);
Toast.makeText(getApplicationContext(), "List Updated", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(exit_Activity.this, error.getMessage(), Toast.LENGTH_LONG).show();
error.printStackTrace();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(request);
}
private void Filter(String text) {
for (Employee post : employeeArrayList) {
String filterPattern = text.toLowerCase().trim();
if (post.getnumber().toLowerCase().contains(filterPattern)) {
filterList.add(post);
}
}
removeView.setAdapter(new MyAdapter(getApplicationContext(), filterList));
adapter.notifyDataSetChanged();
}
MyAdapter.class:
public class MyAdapter extends ArrayAdapter<Employee> implements Filterable{
Context context;
List<Employee> arrayListEmployee;
public MyAdapter(#NonNull Context context, List<Employee> arrayListEmployee) {
super(context, R.layout.custom_list_item,arrayListEmployee);
this.context = context;
this.arrayListEmployee = arrayListEmployee;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_list_item,null,true);
TextView tvID = view.findViewById(R.id.txt_id);
TextView tvName = view.findViewById(R.id.view_vehicle_number);
tvID.setText(arrayListEmployee.get(position).getId());
tvName.setText(arrayListEmployee.get(position).getnumber());
return view;
}
#Override
public int getCount() {
return super.getCount();
}
Pls explain in easy language and provide my solution. I'm new to android studio. thank you x1000 in Advance
I found problem in method (check comments):
private void Filter(String text) {
for (Employee post : employeeArrayList) {
String filterPattern = text.toLowerCase().trim();
if (post.getnumber().toLowerCase().contains(filterPattern)) {
filterList.add(post);
}
}
//below every time you create new instance of MyAdapter - try comment this line (below) and test it
removeView.setAdapter(new MyAdapter(getApplicationContext(), filterList));
//this is your first instance but you set new adapter for listView
adapter.notifyDataSetChanged();
}
and replace your method with this:
private void Filter(String text) {
for (Employee post : employeeArrayList) {
String filterPattern = text.toLowerCase().trim();
if (post.getnumber().toLowerCase().contains(filterPattern)) {
filterList.add(post);
}
}
adapter.clear()
adapter.addAll(filterList);
}
So you don't create a new instance of the adapter every time, just swap data of the existing adapter
I haven't tested it but it should work fine with OnItemClickListener...
EDITED
Also same problem...
#Override
public void afterTextChanged(Editable s) {
filterList.clear();
if (s.toString().isEmpty()) {
//you set new instance of adapter and notify old, try comment this line (below) and test it
//removeView.setAdapter(new MyAdapter(getApplicationContext(), employeeArrayList));
adapter.notifyDataSetChanged();
} else {
Filter(s.toString());
}
}
Change to this
#Override
public void afterTextChanged(Editable s) {
if (!s.toString().isEmpty()) {
filterList.clear(); //TODO here is problem, move this to your filter method
Filter(s.toString());
} else {
//Do nothing, if the EditText field is empty the list will remain filled
}
}
There are other ways to solve this and improve but I don't want to confuse you, because android is new experience for you
EDITED
You are using an ArrayAdapter but I thought it is RecyclerView, forget swapData method and try new changes... Sorry
adapter.clear()
adapter.addAll(filterList);
Hi in the below code I am getting the below error for displaying a list using recyclerview .
When I am trying to display the list I am getting the below error.
java.lang.ClassCastException: java.lang.String cannot be cast to helper.GetBuildingList
at com.deepshikha.lightingsystem.SwipeRecyclerViewAdapter.onBindViewHolder(SwipeRecyclerViewAdapter.java:41)
at com.deepshikha.lightingsystem.SwipeRecyclerViewAdapter.onBindViewHolder(SwipeRecyclerViewAdapter.java:22)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6781)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6823)
Response :
[{"ID":"1","Name":"Building1"},{"ID":"2","Name":"appexx"}]
In the below adapter displays the what are the item presents in the getbuildinglist pojo class.As well as Once user swiped from right to left .We are displaying two options for the list items to edit and delete the items.
SwipeAdapter:
public class SwipeRecyclerViewAdapter extends RecyclerSwipeAdapter<SwipeRecyclerViewAdapter.SimpleViewHolder> {
private Context mContext;
private List<GetBuildingList> buildingLists;
public SwipeRecyclerViewAdapter(Context context, List<GetBuildingList> strings) {
this.mContext = context;
this.buildingLists = strings;
}
#Override
public SimpleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item, parent, false);
return new SimpleViewHolder(view);
}
#Override
public void onBindViewHolder(final SimpleViewHolder viewHolder, final int position) {
final GetBuildingList item = buildingLists.get(position);
System.out.println ("item"+item);
viewHolder.tvName.setText((item.getName ()) + " - Row Position " + position);
System.out.println (item.getName ());
viewHolder.swipeLayout.setShowMode(SwipeLayout.ShowMode.PullOut);
// Drag From Left
// viewHolder.swipeLayout.addDrag(SwipeLayout.DragEdge.Left, viewHolder.swipeLayout.findViewById(R.id.bottom_wrapper1));
// Drag From Right
viewHolder.swipeLayout.addDrag(SwipeLayout.DragEdge.Right, viewHolder.swipeLayout.findViewById(R.id.bottom_wrapper));
// Handling different events when swiping
viewHolder.swipeLayout.addSwipeListener(new SwipeLayout.SwipeListener() {
#Override
public void onClose(SwipeLayout layout) {
//when the SurfaceView totally cover the BottomView.
}
#Override
public void onUpdate(SwipeLayout layout, int leftOffset, int topOffset) {
//you are swiping.
}
#Override
public void onStartOpen(SwipeLayout layout) {
}
#Override
public void onOpen(SwipeLayout layout) {
//when the BottomView totally show.
}
#Override
public void onStartClose(SwipeLayout layout) {
}
#Override
public void onHandRelease(SwipeLayout layout, float xvel, float yvel) {
//when user's hand released.
}
});
/*viewHolder.swipeLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if ((((SwipeLayout) v).getOpenStatus() == SwipeLayout.Status.Close)) {
//Start your activity
Toast.makeText(mContext, " onClick : " + item.getName() + " \n" + item.getEmailId(), Toast.LENGTH_SHORT).show();
}
}
});*/
viewHolder.swipeLayout.getSurfaceView().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mContext, " onClick : " + item.getName () + " \n" + item.getID (), Toast.LENGTH_SHORT).show();
}
});
// viewHolder.btnLocation.setOnClickListener(new View.OnClickListener() {
// #Override
// public void onClick(View v) {
//
// Toast.makeText(v.getContext(), "Clicked on Map " + viewHolder.tvName.getText().toString(), Toast.LENGTH_SHORT).show();
// }
// });
//
//
// viewHolder.tvShare.setOnClickListener(new View.OnClickListener() {
// #Override
// public void onClick(View view) {
//
// Toast.makeText(view.getContext(), "Clicked on Share " + viewHolder.tvName.getText().toString(), Toast.LENGTH_SHORT).show();
// }
// });
viewHolder.tvEdit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(view.getContext(), "Clicked on Edit " + viewHolder.tvName.getText().toString(), Toast.LENGTH_SHORT).show();
}
});
viewHolder.tvDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mItemManger.removeShownLayouts(viewHolder.swipeLayout);
buildingLists.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, buildingLists.size());
mItemManger.closeAllItems();
Toast.makeText(view.getContext(), "Deleted " + viewHolder.tvName.getText().toString(), Toast.LENGTH_SHORT).show();
}
});
// mItemManger is member in RecyclerSwipeAdapter Class
mItemManger.bindView(viewHolder.itemView, position);
}
#Override
public int getItemCount() {
return buildingLists.size();
}
#Override
public int getSwipeLayoutResourceId(int position) {
return R.id.swipe;
}
// ViewHolder Class
public static class SimpleViewHolder extends RecyclerView.ViewHolder {
SwipeLayout swipeLayout;
TextView tvName;
TextView tvDelete;
TextView tvEdit;
public SimpleViewHolder(View itemView) {
super(itemView);
swipeLayout = (SwipeLayout) itemView.findViewById(R.id.swipe);
tvName = (TextView) itemView.findViewById(R.id.tvName);
// tvEmailId = (TextView) itemView.findViewById(R.id.tvEmailId);
tvDelete = (TextView) itemView.findViewById(R.id.tvDelete);
tvEdit = (TextView) itemView.findViewById(R.id.tvEdit);
// tvShare = (TextView) itemView.findViewById(R.id.tvShare);
// btnLocation = (ImageButton) itemView.findViewById(R.id.btnLocation);
}
}
}
In the below code describes the without refreshing the activity I am getting the response from the server.
That response I am adding to arraylist then setting the adapter to the recyclerview to display the list of items with swipe options.
Add.java:
private void doTheAutoRefresh() {
handler.postDelayed(new Runnable() {
#Override
public void run() {
// Write code for your refresh logic
progressDialog = new ProgressDialog (getActivity ());
progressDialog.setIndeterminate(true);
progressDialog.setMessage("Communicating...");
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setCancelable(false);
progressDialog.show();
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API.URL_BASE)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client (client)
.build();
API service = retrofit.create (API.class);
Call<List<GetBuildingList>> userCall = service.getbuildinglist ();
userCall.enqueue(new Callback<List<GetBuildingList>> () {
#Override
public void onResponse(Call <List<GetBuildingList>> call, Response <List<GetBuildingList>> response) {
if(response.isSuccessful()) {
progressDialog.dismiss ( );
Log.d ("Response body", new Gson ( ).toJson (response.body ( )));
String Status = new Gson ( ).toJson (response.body ( ));
JSONArray jsonArray = null;
try {
JSONObject jsonObject=null;
jsonArray = new JSONArray (Status);
arrayList = new ArrayList <> ( );
for (int i=0;i<jsonArray.length ();i++) {
name=jsonArray.getJSONObject (i).getString ("Name");
arrayList.add (name);
}
// Creating Adapter object
SwipeRecyclerViewAdapter mAdapter = new SwipeRecyclerViewAdapter((Context) getActivity (), arrayList);
mAdapter.notifyDataSetChanged ();
mRecyclerView.setAdapter(mAdapter);
} catch (JSONException e) {
e.printStackTrace ( );
}
}
else {
progressDialog.dismiss ();
Log.d("Response errorBody", String.valueOf(response.errorBody()));
}
}
#Override
public void onFailure(Call<List<GetBuildingList>> call, Throwable t) {
// lv.setAdapter (adapter);
System.out.println("onFailure");
System.out.println(t.fillInStackTrace());
progressDialog.dismiss();
Toast.makeText(getActivity (), "Some error occurred -> ", Toast.LENGTH_LONG).show();;
// progressDialog.dismiss();
}
});
}
}, 5000);
return ;
}
GetBuildingList.java:
public class GetBuildingList{
#SerializedName("ID")
private String ID;
#SerializedName("Name")
private String Name;
public String getID() {
return ID;
}
public void setID(String ID) {
this.ID = ID;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
}
In your onResponse() method you have these lines:
name=jsonArray.getJSONObject (i).getString ("Name");
...
arrayList.add (name);
Then you pass this list to your adapter. This list is assigned to the GetBuildingList field of your adapter. Then in your adapter you do:
final GetBuildingList item = buildingLists.get(position);
So you're trying to cast String type to GetBuildingList type, hence the exception.
Not really familiar with the library but you should try something like this:
for (int i=0;i<jsonArray.length ();i++) {
String name = jsonArray.getJSONObject (i).getString ("Name");
String id = jsonArray.getJSONObject (i).getString ("Id");
GetBuildingList gbl = new GetBuildingList();
gbl.setId(id);
gbl.setName(name);
arrayList.add(gbl);
}
I haven't used this library yet so if I'm wrong, someone please correct the above sample.
sorry if the explanation is incomplete. I just learned about Android. and in my project this time, I made a filter feature using the radio button
I followed a totorial, but the tutorial uses static data, then I change it to dynamic using my data in the database. all works !! the data appears
but when I type something in the search bar that I make, suddenly my data disappears, I make 3 radio buttons to be selected by the user to be searched / filtered, namely type, price and facilities. the three radio buttons don't work, my data that appears are gone.
How to handle that problem?? if anyone can help me please help, thank you
this is the code
this fragment
public class FilterFragment extends Fragment implements RadioGroup.OnCheckedChangeListener, View.OnClickListener {
private static final String data_url = "http://000.000.00.000/kos/get_kos.php";
RecyclerView mRecyclerView;
ProgressDialog pd;
private Context context;
private RecyclerViewAdapter adapter;
private ArrayList<UserModel> arrayList;
private RadioGroup searchViaRadioGroup;
private EditText searchEditText;
private TextView searchViaLabel;
/* Filter Type to identify the type of Filter */
private FilterType filterType;
/* boolean variable for Filtering */
private boolean isSearchWithPrefix = false;
public FilterFragment() {
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
this.context = context;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_filter, container, false);
pd = new ProgressDialog(getActivity());
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
arrayList = new ArrayList<>();
mRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(), LinearLayoutManager.VERTICAL));
adapter = new RecyclerViewAdapter(getActivity(), arrayList);
mRecyclerView.setAdapter(adapter);
loadjson();
return view;
}
private void loadjson(){
pd.setMessage("Mengambil Data");
pd.setCancelable(false);
pd.show();
JsonArrayRequest arrayRequest = new JsonArrayRequest(Request.Method.POST, data_url, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
pd.cancel();
Log.d("volley", "response : " + response.toString());
for (int i=0; i < response.length(); i++)
try {
JSONObject data = response.getJSONObject(i);
UserModel md = new UserModel();
md.setJudul(data.getString("judul")); // memanggil nama array yang kita buat
md.setAlamat(data.getString("alamat"));
md.setHarga(data.getString("harga"));
md.setTipe_kos(data.getString("tipe_kos"));
md.setFasilitas(data.getString("fasilitas"));
arrayList.add(md);
} catch (JSONException e) {
e.printStackTrace();
}
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError error) {
pd.cancel();
Log.d("volley", "error : " + error.getMessage());
}
});
Controller.getInstance().addToRequestQueue(arrayRequest);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
findViews(view);
implementEvents();
}
//Bind all Views
private void findViews(View view) {
filterType = FilterType.TIPE_KOS;
searchViaRadioGroup = (RadioGroup) view.findViewById(R.id.search_via_radio_group);
searchEditText = (EditText) view.findViewById(R.id.search_text);
searchViaLabel = (TextView) view.findViewById(R.id.search_via_label);
}
//Populate recycler view
private void implementEvents() {
searchViaRadioGroup.setOnCheckedChangeListener(this);
searchViaLabel.setOnClickListener(this);
searchEditText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
//On text changed in Edit text start filtering the list
adapter.filter(filterType, charSequence.toString(), isSearchWithPrefix);
}
#Override
public void afterTextChanged(Editable editable) {
}
});
}
#Override
public void onCheckedChanged(RadioGroup radioGroup, int checkedId) {
int pos = radioGroup.indexOfChild(radioGroup.findViewById(checkedId));//get the checked position of radio button
switch (radioGroup.getId()) {
case R.id.search_via_radio_group:
switch (pos) {
case 0:
filterType = FilterType.TIPE_KOS;//Change filter type to Name if pos = 0
break;
case 1:
filterType = FilterType.NUMBER;//Change filter type to Number if pos = 1
break;
case 2:
filterType = FilterType.EMAIL;//Change filter type to Email if pos = 2
break;
}
}
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.search_via_label:
//show hide the radio group
if (searchViaRadioGroup.isShown()) {
searchViaLabel.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.up_dropdown, 0);
searchViaRadioGroup.setVisibility(View.GONE);
} else {
searchViaLabel.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.down_dropdown, 0);
searchViaRadioGroup.setVisibility(View.VISIBLE);
}
break;
}
}
}
this adapter
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolder> {
static class RecyclerViewHolder extends RecyclerView.ViewHolder {
private TextView judul, alamat, tipe_kos, fasilitas, harga;
RecyclerViewHolder(View view) {
super(view);
judul = (TextView) view.findViewById(R.id.judul);
alamat = (TextView) view.findViewById(R.id.alamat);
tipe_kos = (TextView) view.findViewById(R.id.tipe_kos);
fasilitas = (TextView) view.findViewById(R.id.fasilitas);
harga = (TextView) view.findViewById(R.id.harga);
}
}
private ArrayList<UserModel> arrayList;
private ArrayList<UserModel> filterArrayList;//duplicate list for filtering
private Context context;
public RecyclerViewAdapter(Context context, ArrayList<UserModel> arrayList) {
this.arrayList = arrayList;
this.context = context;
this.filterArrayList = new ArrayList<>();//initiate filter list
this.filterArrayList.addAll(arrayList);//add all items of array list to filter list
}
#Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.custom_list_filter, viewGroup, false);
return new RecyclerViewHolder(v);
}
#Override
public void onBindViewHolder(final RecyclerViewHolder holder, final int i) {
final UserModel model = arrayList.get(i);
holder.judul.setText(model.getJudul());//menampilkan data
holder.alamat.setText(model.getAlamat());
holder.harga.setText(model.getHarga());
holder.tipe_kos.setText(model.getTipe_kos());
holder.fasilitas.setText(model.getFasilitas());
}
#Override
public int getItemCount() {
return (null != arrayList ? arrayList.size() : 0);
}
// Filter Class to filter data
public void filter(FilterType filterType, String charText, boolean isSearchWithPrefix) {
//If Filter type is TIPE_KOS and EMAIL then only do lowercase, else in case of NUMBER no need to do lowercase because of number format
if (filterType == FilterType.TIPE_KOS || filterType == FilterType.EMAIL)
charText = charText.toLowerCase(Locale.getDefault());
arrayList.clear();//Clear the main ArrayList
//If search query is null or length is 0 then add all filterList items back to arrayList
if (charText.length() == 0) {
arrayList.addAll(filterArrayList);
} else {
//Else if search query is not null do a loop to all filterList items
for (UserModel model : filterArrayList) {
//Now check the type of search filter
switch (filterType) {
case TIPE_KOS:
if (isSearchWithPrefix) {
//if STARTS WITH radio button is selected then it will match the exact TIPE_KOS which match with search query
if (model.getTipe_kos().toLowerCase(Locale.getDefault()).startsWith(charText))
arrayList.add(model);
} else {
//if CONTAINS radio button is selected then it will match the TIPE_KOS wherever it contains search query
if (model.getTipe_kos().toLowerCase(Locale.getDefault()).contains(charText))
arrayList.add(model);
}
break;
case EMAIL:
if (isSearchWithPrefix) {
//if STARTS WITH radio button is selected then it will match the exact EMAIL which match with search query
if (model.getFasilitas().toLowerCase(Locale.getDefault()).startsWith(charText))
arrayList.add(model);
} else {
//if CONTAINS radio button is selected then it will match the EMAIL wherever it contains search query
if (model.getFasilitas().toLowerCase(Locale.getDefault()).contains(charText))
arrayList.add(model);
}
break;
case NUMBER:
if (isSearchWithPrefix) {
//if STARTS WITH radio button is selected then it will match the exact NUMBER which match with search query
if (model.getHarga().startsWith(charText))
arrayList.add(model);
} else {
//if CONTAINS radio button is selected then it will match the NUMBER wherever it contains search query
if (model.getHarga().contains(charText))
arrayList.add(model);
}
break;
}
}
}
notifyDataSetChanged();
}
}
this FilterType
public enum FilterType {
TIPE_KOS, NUMBER, EMAIL;
}
and this user model
package com.example.asus.myapplication.fragment.filter;
public class UserModel {
private String judul, alamat, harga, tipe_kos, fasilitas;
public String getJudul() {
return judul;
}
public String getAlamat() {
return alamat;
}
public String getHarga() {
return harga;
}
public String getTipe_kos() {
return tipe_kos;
}
public String getFasilitas() {
return fasilitas;
}
public void setJudul(String mJudul) {
judul = mJudul;
}
public void setAlamat(String mAlamat) {
alamat = mAlamat;
}
public void setHarga(String mHarga) {
harga = mHarga;
}
public void setTipe_kos(String mTipe_kos) {
tipe_kos = mTipe_kos;
}
public void setFasilitas(String mFasilitas) { fasilitas= mFasilitas;
}
}
another one I do not understand at all for this filter API, I just pulled all the data in my database
My database is like this, which I circle, that's the data I want to filter later
I have a recyclerview and set text some textview in it. when I scroll down or my fragment goes to onPause state my data loss.
what can i do?
import static com.test.mohammaddvi.snappfood.Adapter.SectionListDataAdapter.decodeSampledBitmapFromResource;
public class RecyclerViewMenuFragmentAdapter extends RecyclerView.Adapter<RecyclerViewMenuFragmentAdapter.SingleItemInMenuFragment> {
private ArrayList<Food> foodList;
private Context mContext;
public RecyclerViewMenuFragmentAdapter(ArrayList<Food> foodList, Context mContext) {
this.foodList = foodList;
this.mContext = mContext;
}
#NonNull
#Override
public RecyclerViewMenuFragmentAdapter.SingleItemInMenuFragment onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.foodlist, null);
return new RecyclerViewMenuFragmentAdapter.SingleItemInMenuFragment(v);
}
#Override
public void onBindViewHolder(final RecyclerViewMenuFragmentAdapter.SingleItemInMenuFragment holder, int position) {
Food food = foodList.get(position);
holder.foodName.setText(food.getName());
holder.foodDetails.setText(food.getDetails());
holder.foodPrice.setText(food.getPrice() + " تومان ");
holder.foodOrderNumber.setVisibility(View.INVISIBLE);
holder.foodMinusButton.setVisibility(View.INVISIBLE);
holder.foodOrderNumber.setText(0 + "");
holder.foodImage.setImageBitmap(decodeSampledBitmapFromResource(mContext.getResources(), mContext.getResources().getIdentifier(food.getImage(),
"drawable", mContext.getPackageName()), 50, 50));
handleClick(holder, position);
}
private void handleClick(final SingleItemInMenuFragment holder, final int position) {
holder.foodPlusButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int orderNumber = Integer.parseInt(holder.foodOrderNumber.getText().toString());
holder.foodOrderNumber.setText(orderNumber + 1 + "");
holder.foodOrderNumber.setVisibility(View.VISIBLE);
holder.foodMinusButton.setVisibility(View.VISIBLE);
}
});
holder.foodMinusButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int orderNumber = Integer.parseInt(holder.foodOrderNumber.getText().toString());
if (orderNumber > 1) {
holder.foodOrderNumber.setText(orderNumber - 1 + "");
holder.foodOrderNumber.setVisibility(View.VISIBLE);
}
if (orderNumber == 1) {
holder.foodOrderNumber.setText(orderNumber - 1 + "");
holder.foodOrderNumber.setVisibility(View.INVISIBLE);
holder.foodMinusButton.setVisibility(View.INVISIBLE);
}
}
});
}
#Override
public int getItemCount() {
return (null != foodList ? foodList.size() : 0);
}
public class SingleItemInMenuFragment extends RecyclerView.ViewHolder {
TextView foodName;
TextView foodPrice;
Button foodPlusButton;
Button foodMinusButton;
TextView foodOrderNumber;
ImageView foodImage;
TextView foodDetails;
SingleItemInMenuFragment(View itemView) {
super(itemView);
this.foodName = itemView.findViewById(R.id.foodName);
this.foodImage = itemView.findViewById(R.id.imageFood);
this.foodPrice = itemView.findViewById(R.id.foodPrice);
this.foodDetails = itemView.findViewById(R.id.foodDetails);
this.foodPlusButton = itemView.findViewById(R.id.plusbutton);
this.foodMinusButton = itemView.findViewById(R.id.minusbutton);
this.foodOrderNumber = itemView.findViewById(R.id.ordernumber);
}
}
}
and this is my fragment that i use recyclerview in that:
public class MenuFragment extends Fragment{
private static final String TAG = "menufragment";
ArrayList<Food> allfoods = new ArrayList<>();
RecyclerView recyclerview;
private static Bundle bundle;
private final String KEY_RECYCLER_STATE= "recycler_state";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.menufragment, container, false);
}
#Override
public void onStart() {
super.onStart();
String jsonFilePath = "foods.json";
recyclerview = getActivity().findViewById(R.id.lstitems);
RecyclerViewMenuFragmentAdapter adapter = new RecyclerViewMenuFragmentAdapter(allfoods, getContext());
recyclerview.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
recyclerview.setHasFixedSize(true);
recyclerview.setAdapter(adapter);
parsJson(jsonFilePath);
}
//this method is for read a local json and return a string
public String readLocalJson(String jsonFile) {
String json;
try {
InputStream is = getActivity().getAssets().open(jsonFile);
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, "UTF-8");
} catch (IOException e) {
e.printStackTrace();
return null;
}
return json;
}
public void parsJson(String jsonFilePath) {
try {
JSONObject obj = new JSONObject(readLocalJson(jsonFilePath));
JSONArray jsonArray = obj.getJSONArray("results");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String image = jsonObject.getString("image");
JSONArray jsonArrayFoot = jsonObject.getJSONArray("foots");
for (int j = 0; j < jsonArrayFoot.length(); j++) {
JSONObject jsonObjectFoot = jsonArrayFoot.getJSONObject(j);
String foodName = jsonObjectFoot.getString("name");
String fooddetails = jsonObjectFoot.getString("fooddetails");
String price = jsonObjectFoot.getString("price");
allfoods.add(new Food(foodName, price, fooddetails, image));
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
Basically, you just initialized the data on onStart which will eventually called when your activity/fragment is resumed, and because of that all data you've changed was overwritten to initial data.
Move your onStart initialization to onViewCreated:
#Override
public void onViewCreated() {
super.onViewCreated();
String jsonFilePath = "foods.json";
recyclerview = getActivity().findViewById(R.id.lstitems);
RecyclerViewMenuFragmentAdapter adapter = new RecyclerViewMenuFragmentAdapter(allfoods, getContext());
recyclerview.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
recyclerview.setHasFixedSize(true);
recyclerview.setAdapter(adapter);
parsJson(jsonFilePath);
}
And for scrolling, its normal because RecyclerView recycles the view from the list above but the data is not, so what you need to do is store values from the list source.
#Override
public void onBindViewHolder(final RecyclerViewMenuFragmentAdapter.SingleItemInMenuFragment holder, int position) {
Food food = foodList.get(position);
holder.foodName.setText(food.getName());
holder.foodDetails.setText(food.getDetails());
holder.foodPrice.setText(food.getPrice() + " تومان ");
holder.foodOrderNumber.setVisibility(View.INVISIBLE);
holder.foodMinusButton.setVisibility(View.INVISIBLE);
holder.foodOrderNumber.setText(food.getFoodOrderNumber());
holder.foodImage.setImageBitmap(decodeSampledBitmapFromResource(mContext.getResources(), mContext.getResources().getIdentifier(food.getImage(),
"drawable", mContext.getPackageName()), 50, 50));
handleClick(holder, position);
}
private void handleClick(final SingleItemInMenuFragment holder, final int position) {
holder.foodPlusButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int orderNumber = Integer.parseInt(holder.foodOrderNumber.getText().toString());
int newOrderNumber = orderNumber + 1;
Food food = foodList.get(position);
food.setFoodOrderNumber(newOrderNumber);
holder.foodOrderNumber.setText(newOrderNumber + "");
holder.foodOrderNumber.setVisibility(View.VISIBLE);
holder.foodMinusButton.setVisibility(View.VISIBLE);
}
});
holder.foodMinusButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Food food = foodList.get(position);
int orderNumber = food.getFoodOrderNumber();
if (orderNumber > 1) {
int newOrderNumber = orderNumber - 1;
food.setFoodOrderNumber(newOrderNumber);
holder.foodOrderNumber.setText(newOrderNumber + "");
holder.foodOrderNumber.setVisibility(View.VISIBLE);
}
if (orderNumber == 1) {
int newOrderNumber = orderNumber - 1;
food.setFoodOrderNumber(newOrderNumber);
holder.foodOrderNumber.setText(newOrderNumber + "");
holder.foodOrderNumber.setVisibility(View.INVISIBLE);
holder.foodMinusButton.setVisibility(View.INVISIBLE);
}
}
});
}
And on your Food object just add this field and functions:
public class Food {
int foodOrderNumber;
public int getFoodOrderNumber() {
return foodOrderNumber;
}
public void setFoodOrderNumber(int foodOrderNumber) {
this.foodOrderNumber = foodOrderNumber;
}
}
add this line to your onBindViewHolder method and check again if the problem still exits:
holder.setIsRecyclable(false);