Updating TextView inside ListView Adapter from a Fragment - java

I have a price TextView in my OrderFragment which I would like to update onItemSelected of discount per item and discount per bill Spinner. I tried using notifyDataSetChanged on my ArrayList once I had change the price of my items but it did not update my ListView. The notifyDataSetChanged is working fine when I use it in different fragment for add and removing element from my ArrayList but updating price on the ArrayList for this doesn't seems to be working.
For update my discount per bill, I refer to various question but it doesn't seems to get it working : notifyDataSetChange not working from custom adapter, Android: notifyDataSetChanged(); not working, Android ListView not refreshing after notifyDataSetChanged and others also. Then I tried changing the TextView from my Fragment using ListView.getChildAt() but it is not working due to the ListView only loads the visible rows so, other rows that are not visible are not updated.
As for discount per item, I had it working but by using 2 Callback which seems to be not efficient.
OrderFragment
public class OrderFragment extends Fragment {
private ArrayList<Product> orderList = new ArrayList<Product>();
private ListView lvConfirmOrder;
private ListViewOrderAdapter lvConfirmOrderAdapter;
private TextView tvTotalOrderPrice;
private int totalOrderPrice;
private Spinner sBillDiscount;
private int billDiscount = 0;
private ItemClickListener itemClickListener;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_order, container, false);
activity = getActivity();
db = DatabaseHelper.getInstance(activity);
Bundle bundle = new Bundle();
orderList = getArguments().getParcelableArrayList("orderList");
tvTotalOrderPrice = (TextView) view.findViewById(R.id.tvShowTotalPrice);
sBillDiscount = (Spinner) view.findViewById(R.id.sBillDiscount);
lvConfirmOrder = (ListView) view.findViewById(R.id.lvConfirmOrder);
lvConfirmOrderAdapter = new ListViewOrderAdapter(activity, orderList, new ItemClickListener() {
#Override
public void onItemClick(Product product) {
}
#Override
public void onItemClick(ProductCategory productCategory) {
}
#Override
public void onItemClick(ArrayList<Product> productList) {
tvTotalOrderPrice.setText(String.format("%d",setTotalPrice()));
}
});
lvConfirmOrder.setAdapter(lvConfirmOrderAdapter);
// Get the total price of all items
totalOrderPrice = setTotalPrice();
// Set the total price into TextView
tvTotalOrderPrice.setText(String.format("%d",totalOrderPrice));
addItemsOnSBillDiscountAndPreselect(billDiscount);
sBillDiscount.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
float spinnerValue = Float.parseFloat(adapterView.getItemAtPosition(i).toString());
float discount = 1.0f - (spinnerValue/100.0f);
totalAfterDiscount(discount);
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
return view;
}
private int setTotalPrice() {
int totalPrice = 0;
for (int index = 0; index < orderList.size(); index++) {
totalPrice += orderList.get(index).getOrderPrice();
}
return totalPrice;
}
// add items into spinner
public void addItemsOnSBillDiscountAndPreselect(int discount) {
List<Integer> list = new ArrayList<Integer>();
for(int index = 0; index <= 100; index++) {
list.add(index);
}
ArrayAdapter<Integer> dataAdapter = new ArrayAdapter<Integer>(activity,
android.R.layout.simple_spinner_item, list);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
sBillDiscount.setAdapter(dataAdapter);
int spinnerPosition = dataAdapter.getPosition(discount);
sBillDiscount.setSelection(spinnerPosition);
}
public void totalAfterDiscount(float discount) {
float totalItemPrice[] = new float[orderList.size()];
for (int i = 0; i < orderList.size(); i++) {
totalItemPrice[i] = orderList.get(i).getOrderPrice() * discount;
}
TextView tvPrice;
for ( int i = 0 ; i < lvConfirmOrder.getCount() ; i++){
View v = getViewByPosition(i,lvConfirmOrder);
tvPrice = (TextView) v.findViewById(R.id.tvQtyPrice);
tvPrice.setText(String.valueOf(totalItemPrice[i]));
}
tvTotalOrderPrice.setText(String.format("%d",setTotalPrice()));
lvConfirmOrderAdapter.notifyDataSetChanged();
}
public View getViewByPosition(int position, ListView listView) {
final int firstListItemPosition = listView.getFirstVisiblePosition();
final int lastListItemPosition =firstListItemPosition + listView.getChildCount() - 1;
if (position < firstListItemPosition || position > lastListItemPosition ) {
return listView.getAdapter().getView(position, listView.getChildAt(position), listView);
} else {
final int childIndex = position - firstListItemPosition;
return listView.getChildAt(childIndex);
}
}
}
ListViewOrderAdapter
public class ListViewOrderAdapter extends ArrayAdapter {
//to store the list of products
private ArrayList<Product> productList = new ArrayList<Product>();
private ItemClickListener itemClickListener;
private ViewHolder viewHolder;
private DiscountSpinnerListener discountSpinnerListener;
private static class ViewHolder {
TextView tvProductName;
TextView tvProductSku;
TextView tvPrice;
TextView tvProductNum;
TextView iAddQuantity;
TextView tvQuantity;
TextView tvQtyPrice;
TextView iMinusQuantity;
Spinner sDiscount;
TextView iDelete;
}
public ListViewOrderAdapter(Activity context, ArrayList<Product> listProduct, ItemClickListener itemClickListener){
super(context,R.layout.row_order , listProduct);
this.context = context;
this.productList = listProduct;
this.itemClickListener = itemClickListener;
}
public View getView(final int position, View view, ViewGroup parent) {
final Product product = productList.get(position);
if (view == null) {
// If there's no view to re-use, inflate a brand new view for row
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(context);
view = inflater.inflate(R.layout.row_order, null, false);
viewHolder.tvProductName = (TextView) view.findViewById(R.id.tvOrderProduct);
viewHolder.tvProductSku = (TextView) view.findViewById(R.id.tvOrderSKU);
viewHolder.tvPrice = (TextView) view.findViewById(R.id.tvProductPrice);
viewHolder.tvProductNum = (TextView) view.findViewById(R.id.tvOrderNum);
viewHolder.iAddQuantity = (TextView) view.findViewById(R.id.iAddQuantity);
viewHolder.tvQuantity = (TextView) view.findViewById(R.id.tvQuantity);
viewHolder.tvQtyPrice = (TextView) view.findViewById(R.id.tvQtyPrice);
viewHolder.iMinusQuantity = (TextView) view.findViewById(R.id.iMinusQuantity);
viewHolder.sDiscount = (Spinner) view.findViewById(R.id.sDiscount);
viewHolder.iDelete = (TextView) view.findViewById(R.id.iDelete);
// Cache the viewHolder object inside the fresh view
view.setTag(viewHolder);
} else {
// View is being recycled, retrieve the viewHolder object from tag
viewHolder = (ViewHolder) view.getTag();
}
//this code sets the values of the objects to values from the arrays
viewHolder.tvProductName.setText(product.getProduct_name());
viewHolder.tvProductSku.setText(product.getProduct_sku());
viewHolder.tvPrice.setText(String.valueOf(product.getPrice_max()));
String num = Integer.toString(position + 1);
viewHolder.tvProductNum.setText(num);
viewHolder.tvQuantity.setText(String.valueOf(product.getOrderQuantity()));
addItemsOnSDiscountAndPreselect(viewHolder,product.getDiscount_per_item());
viewHolder.sDiscount.setOnItemSelectedListener(new SpinnerListener(viewHolder, position, new DiscountSpinnerListener() {
#Override
public void onDiscountChange(TextView tvPrice, int pos, float price) {
if (position == pos) {
tvPrice.setText(String.valueOf(price));
itemClickListener.onItemClick(productList);
}
}
}));
font = Typeface.createFromAsset(context.getAssets(), "fonts/fontawesome-webfont.ttf" );
viewHolder.iAddQuantity.setTypeface(font);
viewHolder.iMinusQuantity.setTypeface(font);
viewHolder.iDelete.setTypeface(font);
viewHolder.iAddQuantity.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
product.setOrderQuantity(product.getOrderQuantity() + 1);
product.setOrderPrice(product.getOrderQuantity() * product.getPrice_max());
itemClickListener.onItemClick(productList);
notifyDataSetChanged();
}
});
viewHolder.iMinusQuantity.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
product.setOrderQuantity(product.getOrderQuantity() - 1);
product.setOrderPrice(product.getOrderQuantity() * product.getPrice_max());
if (product.getOrderQuantity() == 0) {
createAndShowAlertDialog(position, productList);
} else {
itemClickListener.onItemClick(productList);
notifyDataSetChanged();
}
}
});
viewHolder.iDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
createAndShowAlertDialog(position, productList);
notifyDataSetChanged();
}
});
return view;
}
private void createAndShowAlertDialog(final int position, final ArrayList<Product> productList) {
AlertDialog.Builder builder = new AlertDialog.Builder(context,R.style.MyDialogTheme);
builder.setTitle("Are you sure you want to delete " + productList.get(position).getProduct_name());
builder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
productList.remove(position);
itemClickListener.onItemClick(productList);
notifyDataSetChanged();
dialog.dismiss();
}
});
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
productList.get(position).setOrderQuantity(1);
dialog.dismiss();
}
});
AlertDialog dialog = builder.create();
dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(false);
dialog.show();
}
// add items into spinner
public void addItemsOnSDiscountAndPreselect(ViewHolder viewHolder, int discount) {
List<Integer> list = new ArrayList<Integer>();
for(int index = 0; index <= 100; index++) {
list.add(index);
}
ArrayAdapter<Integer> dataAdapter = new ArrayAdapter<Integer>(context,
android.R.layout.simple_spinner_item, list);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
viewHolder.sDiscount.setAdapter(dataAdapter);
int spinnerPosition = dataAdapter.getPosition(discount);
viewHolder.sDiscount.setSelection(spinnerPosition);
}
private class SpinnerListener implements AdapterView.OnItemSelectedListener {
private int mSpinnerPosition;
private DiscountSpinnerListener discountSpinnerListener;
private ViewHolder viewHolder;
public SpinnerListener(ViewHolder viewHolder, int spinnerPosition, DiscountSpinnerListener discountSpinnerListener) {
mSpinnerPosition = spinnerPosition;
this.discountSpinnerListener = discountSpinnerListener;
this.viewHolder = viewHolder;
}
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
float spinnerValue = Float.parseFloat(arg0.getItemAtPosition(arg2).toString());
float discount = 1.0f - (spinnerValue/100.0f);
float totalItemPrice = productList.get(mSpinnerPosition).getPrice_max() * productList.get(mSpinnerPosition).getOrderQuantity() * discount;
productList.get(mSpinnerPosition).setOrderPrice(totalItemPrice);
productList.get(mSpinnerPosition).setDiscount_per_item(Integer.parseInt(arg0.getItemAtPosition(arg2).toString()));
// Listener to set total price of an item after discount
discountSpinnerListener.onDiscountChange(viewHolder.tvQtyPrice, mSpinnerPosition, totalItemPrice);
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
}
}
P/S: Please ignore the calculation to get the discount price first, as it does conflict against my both discount spinner(initially I was only implementing the discount per item).
This is screenshot of my app: See here

You are using orderList in your adapter but have you update your orderList after calculating the discount?
if you dont update the data in orderList , notifyDataSetChangeddoesnt really do anything.
hope that helps.

Related

How to get total by adding all the recycler views rows

I have recycler view in my activity and below there is a total cost field which shows the total value comes after adding the values from each row. As shown in the screen below:
In a recycler view, there is a spinner that shows quantity on selecting a value from spinner it will be multiplied by the MRP like this every same row have some values. I want to add this value and want to show it in the Lower left corner.
So far I am sending MRP value from adapter class to activity using LocalBroadcatManager class.
But every time I selecting data from another row it does not add cost with the previous value
but it replaces the older value.
Below is my code:
ProductAdapter.java
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ViewHolder> {
private Context context;
private List<ProductsModel> productList;
public ProductAdapter(Context context, List<ProductsModel> productList) {
this.context = context;
this.productList = productList;
}
#NonNull
#Override
public ProductAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.selectpack_layout,parent,false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull final ProductAdapter.ViewHolder holder, int position) {
final ProductsModel model = productList.get(position);
holder.marketName.setText(model.getMarketName());
holder.productNo.setText(model.getProductNo());
holder.page.setText(model.getPage());
holder.mrp.setText(model.getMrp());
holder.innerPack.setText(model.getInnerPack());
holder.outerPack.setText(model.getOuterPack());
List<String> qty = new ArrayList<>();
qty.add("Select qty");
qty.add("1");
qty.add("2");
qty.add("3");
qty.add("4");
qty.add("5");
qty.add("6");
qty.add("7");
qty.add("8");
qty.add("9");
qty.add("10");
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(context, android.R.layout.simple_spinner_item, qty);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
holder.qtySpinner.setAdapter(dataAdapter);
holder.qtySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
int sum = 0;
String item = adapterView.getItemAtPosition(i).toString();
if (!item.equals("Select qty")) {
int qty = Integer.parseInt(item);
int cost = Integer.parseInt(model.getMrp());
int val = cost * qty;
holder.total.setText(String.valueOf(val));
Intent intent = new Intent("msg");
intent.putExtra("cost", String.valueOf(val));
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
#Override
public int getItemCount() {
return productList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView marketName,productNo,page,mrp,innerPack,outerPack,total;
Spinner qtySpinner;
Button order;
public ViewHolder(#NonNull View itemView) {
super(itemView);
order = itemView.findViewById(R.id.order);
qtySpinner = itemView.findViewById(R.id.qtySpinner);
marketName = itemView.findViewById(R.id.marketName);
productNo = itemView.findViewById(R.id.productNo);
page = itemView.findViewById(R.id.page);
mrp = itemView.findViewById(R.id.mrp);
innerPack = itemView.findViewById(R.id.innerPack);
outerPack = itemView.findViewById(R.id.outerPack);
total = itemView.findViewById(R.id.total);
}
}
}
SelectPack.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_pack);
fAuth = FirebaseAuth.getInstance();
ActionBar ab = getSupportActionBar();
assert ab!= null;
ab.setTitle("Select Pack");
ab.setDisplayHomeAsUpEnabled(true);
marketSpinner = findViewById(R.id.marketSpinner);
progress = findViewById(R.id.progress);
products = findViewById(R.id.products);
totalCost = findViewById(R.id.totalCost);
products.setHasFixedSize(true);
products.setLayoutManager(new LinearLayoutManager(this));
productList = new ArrayList<>();
List<String> categories = new ArrayList<String>();
categories.add("Select market");
categories.add("Crown");
categories.add("Long Book A4");
categories.add("Long Book");
categories.add("Crown Junior");
categories.add("Physics");
categories.add("Chemistry");
categories.add("Biology");
categories.add("Universal");
categories.add("Sketch Book");
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, categories);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
marketSpinner.setAdapter(dataAdapter);
marketSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
String item = adapterView.getItemAtPosition(i).toString();
if(item.equals("Select market")){
progress.setVisibility(View.INVISIBLE);
}
else{
getData(item);
}
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
LocalBroadcastManager.getInstance(SelectPack.this).registerReceiver(message,new IntentFilter("msg"));
}
private void getData(String item){
progress.setVisibility(View.VISIBLE);
products.setVisibility(View.INVISIBLE);
productList.clear();
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.readTimeout(20,TimeUnit.SECONDS)
.writeTimeout(20,TimeUnit.SECONDS)
.build();
RequestBody formBody = new FormBody.Builder()
.add("name",item)
.build();
Request request = new Request.Builder().post(formBody).url(URL).build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onResponse(#NotNull Call call, #NotNull final Response response) throws IOException {
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
JSONArray jsonArray = new JSONArray(response.body().string());
if(jsonArray.length() > 0){
products.setVisibility(View.VISIBLE);
progress.setVisibility(View.INVISIBLE);
}
for(int i=0;i<jsonArray.length();i++){
progress.setVisibility(View.INVISIBLE);
JSONObject object = jsonArray.getJSONObject(i);
String str1 = object.getString("market");
String str2 = object.getString("product_no");
String str3 = object.getString("page");
String str4 = object.getString("mrp");
String str5 = object.getString("inner_pack");
String str6 = object.getString("outer_pack");
Log.d("prod",str2);
ProductsModel model = new ProductsModel(str1,str2,str3,str4,str5,str6);
productList.add(model);
}
ProductAdapter adapter = new ProductAdapter(getApplicationContext(),productList);
products.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
#Override
public void onFailure(#NotNull Call call, #NotNull final IOException e) {
runOnUiThread(new Runnable() {
#Override
public void run() {
progress.setVisibility(View.INVISIBLE);
products.setVisibility(View.INVISIBLE);
Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}
});
}
public BroadcastReceiver message = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String nam = intent.getStringExtra("cost");
if(nam != null){
int val = Integer.parseInt(nam);
totalCost.setText("Total: "+val+".00");
}
}
};
Someone, please let me know what I am doing wrong or how should I implement it correctly. Any help would be appreciated.
THANKS
why you are using local broadcasts to communicate with activity. Instead, use interface to communicate it will be easy to use.
I found the problem when the item is getting selected you are passing the only current value not all the selected value that's why it is showing the latest value instead of all the value.
You should pass all the selected values from the list, let's say If I select one value, keep that in the separate list or you can manage with a flag in the current list object and when user selects any item then loop through that list and add all the price and pass it to activity.
Add one field in ProductsModel called Qty
Here is my updated adapter class I have added a comment as well please try this Hope it helps
public class ProductAdapter extends RecyclerView.Adapter {
private Context context;
private List<ProductsModel> productList;
// add this list
private List<ProductsModel> selectedProductList = new ArrayList();
public ProductAdapter(Context context, List<ProductsModel> productList) {
this.context = context;
this.productList = productList;
}
#NonNull
#Override
public ProductAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.selectpack_layout,parent,false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull final ProductAdapter.ViewHolder holder, int position) {
final ProductsModel model = productList.get(position);
holder.marketName.setText(model.getMarketName());
holder.productNo.setText(model.getProductNo());
holder.page.setText(model.getPage());
holder.mrp.setText(model.getMrp());
holder.innerPack.setText(model.getInnerPack());
holder.outerPack.setText(model.getOuterPack());
List<String> qty = new ArrayList<>();
qty.add("Select qty");
qty.add("1");
qty.add("2");
qty.add("3");
qty.add("4");
qty.add("5");
qty.add("6");
qty.add("7");
qty.add("8");
qty.add("9");
qty.add("10");
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(context, android.R.layout.simple_spinner_item, qty);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
holder.qtySpinner.setAdapter(dataAdapter);
holder.qtySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
int sum = 0;
String item = adapterView.getItemAtPosition(i).toString();
// add this line
adapterView.getItemAtPosition(i);
if (!item.equals("Select qty")) {
// add this line
model.setQty(Integer.parseInt(item));
selectedProductList.add(model);
}
int val = 0;
for(int j = 0; j < selectedProductList.size(); j++){
ProductsModel model = selectedProductList.get(i);
int mrp = model.getMrp();
int qty = model.getQty();
val = val + (mrp * qty);
}
holder.total.setText(String.valueOf(val));
Intent intent = new Intent("msg");
intent.putExtra("cost", String.valueOf(val));
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
#Override
public int getItemCount() {
return productList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView marketName,productNo,page,mrp,innerPack,outerPack,total;
Spinner qtySpinner;
Button order;
public ViewHolder(#NonNull View itemView) {
super(itemView);
order = itemView.findViewById(R.id.order);
qtySpinner = itemView.findViewById(R.id.qtySpinner);
marketName = itemView.findViewById(R.id.marketName);
productNo = itemView.findViewById(R.id.productNo);
page = itemView.findViewById(R.id.page);
mrp = itemView.findViewById(R.id.mrp);
innerPack = itemView.findViewById(R.id.innerPack);
outerPack = itemView.findViewById(R.id.outerPack);
total = itemView.findViewById(R.id.total);
}
}
}

checkbox uncheck and row values of listview are not updated

Confusing at it may seem, I am confused of what is happening too. I have an application in which there is a listview that displays values and when a row is pressed, the third value of the row will display a value.
Example is: third value is 30 and when it's pressed, it should be divided by 6, so the answer should be 5.
But when I scroll in the listview, the checkbox becomes unchecked and the third value of the row goes back to its old value (30).
Is there any way to keep the checkbox from being checked and the value of the row preserved when clicked?
Here's the snippet of my code.
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
CheckBox checkBox = (CheckBox)view.findViewById(R.id.checkmark);
TextView tv3 = (TextView)view.findViewById(R.id.tx_counter);
EditText editText = (EditText)findViewById(R.id.editText3);
String yy = editText.getText().toString().trim();
String shitts = listView.getItemAtPosition(position).toString();
try {
String[] a = shitts.split(", ");
String[] b = a[1].split("=");
String[] sep = a[0].split("=");
String betnumber = sep[1];
String betamount= b[1];
if (view != null) {
checkBox.setChecked(!checkBox.isChecked());
if(checkBox.isChecked()){
//sort number
final String sorted = betnumber.chars().sorted().mapToObj(c -> Character.valueOf((char)c).toString()).collect(Collectors.joining());
System.out.println(sorted);
//check if double digit
Boolean checker = doubleChecker(sorted);
if (checker == true){
Toast.makeText(getApplicationContext(),"DOUBLE DIGIT", LENGTH_SHORT).show();
int answer = Integer.parseInt(betamount) / 3;
tv3.setText(String.valueOf(answer));
}else{
Toast.makeText(getApplicationContext(),"NOT DOUBLE DIGIT", LENGTH_SHORT).show();
int answer;
if(yy.equals("")){
answer = Integer.parseInt(betamount) / 6;
tv3.setText(String.valueOf(answer));
}else{
answer = (Integer.parseInt(betamount) - Integer.parseInt(yy)) / 6;
tv3.setText(String.valueOf(answer));
}
}
//TODO save to array to send
}else{
//TODO mistake RETURN tv3 to old value
}
}
}catch (Exception e){
}
}
});
Here's my adapter.
class MyAdapter extends BaseAdapter {
private ArrayList<HashMap<String, String>> mData;
public MyAdapter(ArrayList<HashMap<String, String>> mData2) {
this.mData = mData2;
}
#Override
public int getCount() {
return mData.size();
}
#Override
public Object getItem(int i) {
return this.mData.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
view = getLayoutInflater().inflate(R.layout.row_layout, null);
TextView tx_number = (TextView) view.findViewById(R.id.tx_number);
TextView tx_amount = (TextView) view.findViewById(R.id.tx_amount);
TextView tx_counter = (TextView) view.findViewById(R.id.tx_counter);
String betid = mData.get(i).get("betid");
if(betid!=null){
String betnumber = mData.get(i).get("betnumber");
String amountTarget = mData.get(i).get("amountTarget");
String amountRamble = mData.get(i).get("amountRamble");
tx_number.setText(betnumber);
tx_amount.setText(amountTarget);
tx_counter.setText(amountRamble);
}
return view;
}
}
Replace your adapter code with:
public class MyAdapter extends BaseAdapter {
private ArrayList<HashMap<String, String>> mData;
public MyAdapter(ArrayList<HashMap<String, String>> mData2) {
this.mData = mData2;
}
#Override
public int getCount() {
return mData.size();
}
#Override
public Object getItem(int i) {
return this.mData.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
View mView = convertView;
String betid = mData.get(i).get("betid");
ViewHolder holder ;
if (mView == null) {
Context context = viewGroup.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
mView = inflater.inflate(R.layout.row_layout, null,false);
holder = new ViewHolder();
holder.tx_number = (TextView) mView.findViewById(R.id.tx_number);
holder.tx_amount = (TextView) mView.findViewById(R.id.tx_amount);
holder.tx_counter = (TextView) mView.findViewById(R.id.tx_counter);
mView.setTag(holder);
} else {
holder = (ViewHolder) mView.getTag();
}
if (betid != null) {
String betnumber = mData.get(i).get("betnumber");
String amountTarget = mData.get(i).get("amountTarget");
String amountRamble = mData.get(i).get("amountRamble");
holder.tx_number.setText(betnumber);
holder.tx_amount.setText(amountTarget);
holder.tx_counter.setText(amountRamble);
}
return mView;
}
private static class ViewHolder {
TextView tx_number;
TextView tx_amount;
TextView tx_counter;
}
}
I added new code with ViewHolder.

Update textview from Recyclerview Adapter class

I'm working on a E-commerce App to place some online orders. In my Recyclerview there are products, which are added at the previous activity. Here i'm populating the added products in the Recyclerview with the details such as item name, qty, price etc.. There are buttons to increase/decrease the qty of each products and another button to delete the item too.
At the bottom of the Recyclerview Layout there is another textview to Show the grand total. As I'm handling the button slicks in the RecyclerViewAdapter class, while user updating the qty or deleting an item, I have to update the Grand total. I tried some solutions already mentioned here, but the app crashes at random button clicks. Please provide a solution or a better way to do this.
Here is my Adapter class:
public class InvoiceRecyclerViewAdapter extends RecyclerView.Adapter<InvoiceRecyclerViewAdapter.ViewHolder> {
private static final String TAG = "RecylerViewAdapter";
List<Products> addedProductsList;
Context mContext;
public InvoiceRecyclerViewAdapter(Context mContext,List<Products> addedProductsList)
{
this.mContext=mContext;
this.addedProductsList=addedProductsList;
}
public InvoiceRecyclerViewAdapter(Context mContext)
{
this.mContext=mContext;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_invoice,parent,false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, final int position) {
holder.item_qty.setText("1");
holder.itemname.setText(addedProductsList.get(position).getName());
holder.itemprice.setText("Rs "+addedProductsList.get(position).getPrice());
holder.itemdiscount.setText("Rs "+calculate_dis(position));
holder.itemtotal.setText("Rs "+calculate_total(position));
holder.button_inc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int qty = addedProductsList.get(position).getQty();
qty++;
addedProductsList.get(position).setQty(qty);
holder.item_qty.setText(""+qty);
holder.itemdiscount.setText("Rs "+calculate_dis(position));
holder.itemtotal.setText("Rs "+calculate_total(position));
UpdateTotal();
}
});
holder.button_dec.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int qty = addedProductsList.get(position).getQty();
qty--;
if(qty>0){
addedProductsList.get(position).setQty(qty);
holder.item_qty.setText(""+qty);
holder.itemdiscount.setText("Rs"+calculate_dis(position));
holder.itemtotal.setText("Rs"+calculate_total(position));
UpdateTotal();
}
}
});
holder.button_cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addedProductsList.get(position).setAddedTocart(false);
//notifyDataSetChanged();
addedProductsList.remove(position);
notifyItemRemoved(position);
UpdateTotal();
}
});
}
#Override
public int getItemCount() {
return addedProductsList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView itemname,itemtotal,itemprice,itemdiscount,item_qty;
Button button_cancel,button_inc,button_dec;
ConstraintLayout parent_layout;
public ViewHolder(View itemView) {
super(itemView);
itemname = itemView.findViewById(R.id.textView_item_name);
itemprice = itemView.findViewById(R.id.textView_item_price);
itemdiscount = itemView.findViewById(R.id.textView_item_discount);
itemtotal = itemView.findViewById(R.id.textView_item_total);
button_cancel = itemView.findViewById(R.id.button_cancel);
button_inc=itemView.findViewById(R.id.button_inc);
button_dec=itemView.findViewById(R.id.button_dec);
item_qty = itemView.findViewById(R.id.textView_qty);
parent_layout = itemView.findViewById(R.id.invoice_parent_layout);
}
}
private float calculate_dis(int pos){
float dis = 0;
if(addedProductsList.get(pos).isPrice_g_enabled()){
int qty=addedProductsList.get(pos).getQty();
dis = Float.parseFloat(addedProductsList.get(pos).getPrice())-Float.parseFloat(addedProductsList.get(pos).getPrice_g());
dis = qty*dis;
}
return dis;
}
private float calculate_total(int pos){
int qty=addedProductsList.get(pos).getQty();
float price,total;
if(addedProductsList.get(pos).isPrice_g_enabled()){
price = Float.parseFloat(addedProductsList.get(pos).getPrice_g());
}
else{
price= Float.parseFloat(addedProductsList.get(pos).getPrice());
}
total = price*qty;
return total;
}
private void UpdateTotal(){
TextView txtView =((EditQuantity)mContext).findViewById(R.id.textView_total);
float total=0,price=0;
int qty=0;
for(int i=0;i<addedProductsList.size();i++){
if(addedProductsList.get(i).isAddedTocart()) {
qty = addedProductsList.get(i).getQty();
if(addedProductsList.get(i).isPrice_g_enabled()){
price = Float.parseFloat(addedProductsList.get(i).getPrice_g());
}
else{
price= Float.parseFloat(addedProductsList.get(i).getPrice());
}
}
total=total+(qty*price);
}
txtView.setText("Rs "+total);
}
}
Here is the Main Activity part:
public class EditQuantity extends AppCompatActivity {
ArrayList<Products> products_list;
ArrayList<Products> cart_productslist= new ArrayList<>();
Products added_product;
FloatingActionButton fab_next;
TextView total_textview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_quantity);
products_list = getIntent().getParcelableArrayListExtra("products");
Products products;
for(int i=0;i<products_list.size();i++){
products = products_list.get(i);
if(products.isAddedTocart()){
added_product = new Products(products.getName(),products.getPrice(),products.getPrice_g(),products.getImage(),1,true,products.isPrice_g_enabled());
cart_productslist.add(added_product);
}
}
Toolbar toolbar = findViewById(R.id.toolbar_invoice);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Cart");
total_textview = findViewById(R.id.textView_total);
total_textview.setText("Rs "+CalTotal());
fab_next = findViewById(R.id.fab_next);
fab_next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
InitRecylerView();
}
#Override
public void onBackPressed() {
}
private void InitRecylerView() {
RecyclerView recyclerView = findViewById(R.id.invoice_recyclerview);
InvoiceRecyclerViewAdapter adapter = new InvoiceRecyclerViewAdapter(
this ,cart_productslist);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
public float CalTotal(){
float total=0;
float i_total,price;
for(int i=0;i<cart_productslist.size();i++){
if(cart_productslist.get(i).isAddedTocart()) {
int qty = cart_productslist.get(i).getQty();
if(cart_productslist.get(i).isPrice_g_enabled()){
price = Float.parseFloat(cart_productslist.get(i).getPrice_g());
}
else{
price= Float.parseFloat(cart_productslist.get(i).getPrice());
}
i_total = price * qty;
total = total + i_total;
}
}
return total;
}
I'd suggest going through a listener, moving your onClickListeners and removing the for loops.
So, step by step
In your adapter class declare an interface
public interface OnQuantityChangeListener {
void onQuantityChange( float change );
}
Next add a private OnQuantityChangeListener to your adapter class and change the constructor to add one at creation:
private OnQuantityChangeListener mListener;
public InvoiceRecyclerViewAdapter(Context mContext,List<Products> addedProductsList, OnQuantityChangeListener listener) {
this.mContext=mContext;
this.addedProductsList=addedProductsList;
mListener = listener;
}
public InvoiceRecyclerViewAdapter(Context mContext, OnQuantityChangeListener listener)
{
this.mContext=mContext;
mListener = listener;
}
It's bad for performance to set OnClickListeners in the onBindViewHolder method, because this means you're going to have to add them any time a view pops up onto the screen. Set them in the onCreateViewHolder method instead, that way you'll recycle them. To get your current item you can use the getAdapterPosition() method.
So in the onCreateViewHolder method set the listeners:
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_invoice,parent,false);
ViewHolder viewHolder = new ViewHolder(view);
viewHolder.button_inc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Products product = addedProductsList.get(getAdapterPosition());
product.setQty( product.getQty() + 1 );
float difference = product.isPrice_g_enabled() ? Float.parseFloat(product.getPrice_g()) : Float.parseFloat(product.getPrice());
mListener.onQuantityChange( difference );
notifyItemChanged( getAdapterPosition ):// This will call onBindViewAdapter again and change all your strings for you
}
});
viewHolder.button_dec.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Products product = addedProductsList.get(getAdapterPosition());
if( product.getQty() == 0 )// Can't remove an item if it's already at 0
return;
product.setQty( product.getQty() - 1 );
float difference = product.isPrice_g_enabled() ? Float.parseFloat(product.getPrice_g()) : Float.parseFloat(product.getPrice());
mListener.onQuantityChange( -difference );
notifyItemChanged( getAdapterPosition ):// This will call onBindViewAdapter again and change all your strings for you
}
});
viewHolder.button_cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Products product = addedProductsList.get(getAdapterPosition());
float difference = product.isPrice_g_enabled() ? Float.parseFloat(product.getPrice_g()) : Float.parseFloat(product.getPrice());
mListener.onQuantityChange( -difference * product.getQty() );
product.setQty( 0 );
notifyItemChanged( getAdapterPosition ):// This will call onBindViewAdapter again and change all your strings for you
// You decide at this point if you want to remove the item altogether or just show 0
}
});
return viewHolder;
}
Remember at this point to remove the OnClickListeners from your onBindViewHolder method.
Once this is done head over to your Activity and add a private total:
private float total = 0;
and edit your adapter creation like so:
InvoiceRecyclerViewAdapter adapter = new InvoiceRecyclerViewAdapter(
this ,cart_productslist, new InvoiceRecyclerViewAdapter.OnQuantityChangeListener(){
#Override
void onQuantityChange( float difference ){
total += difference;
total_textview.setText("Rs "+ total);
}
} );
And that about does it. Remember to calculate your first total in your activity once (no escaping the for loop here) and then make sure you save your instance states.
Hope this helps!

How avoid refresh checkbox while expand list in android

I'm making NLevel expandable list using listview. I've added checkbox only last level data in list view. I have stuck in below scenario.
If I check checkbox then when I expand listview means checkbox gets automatically unchecked.I don't want it to be like that. If I checked checkbox it should stay checked until I uncheck manually.
Please anyone help me!! It's been two days I stuck here.
Here goes my code:
MainActivity.java
public class MainActivity extends Activity {
List<NLevelItem> list;
ListView listView;
Context context;
Button checkButton;
ArrayList<String>tempList;
CheckBox selected = null; //Make only one selection at a time
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView1);
list = new ArrayList<NLevelItem>();
context = this;
checkButton = (Button)findViewById(R.id.buttons);
tempList = new ArrayList<String>();
//here we create 5 grandparent (top level) NLevelItems
//then foreach grandparent create a random number of parent (second level) NLevelItems
//then foreach parent create a random number of children (third level) NLevelItems
//we pass in an anonymous instance of NLevelView to the NLevelItem, this NLevelView is
//what supplies the NLevelAdapter with a View for this NLevelItem
Random rng = new Random();
final LayoutInflater inflater = LayoutInflater.from(this);
for (int i = 0; i < 5; i++) {
final NLevelItem grandParent = new NLevelItem(new SomeObject("GrandParent "+i),null, new NLevelView() {
#Override
public View getView(NLevelItem item) {
View view = inflater.inflate(R.layout.list_item, null);
TextView tv = (TextView) view.findViewById(R.id.textView);
//tv.setBackgroundColor(Color.GREEN);
String name = (String) ((SomeObject) item.getWrappedObject()).getName();
tv.setText(name);
return view;
}
});
list.add(grandParent);
int numChildren = rng.nextInt(4) + 1;
for (int j = 0; j < numChildren; j++) {
NLevelItem parent = new NLevelItem(new SomeObject("Parent "+j),grandParent, new NLevelView() {
#Override
public View getView(NLevelItem item) {
View view = inflater.inflate(R.layout.list_item, null);
TextView tv = (TextView) view.findViewById(R.id.textView);
//tv.setBackgroundColor(Color.YELLOW);
String name = (String) ((SomeObject) item.getWrappedObject()).getName();
tv.setText(name);
return view;
}
});
list.add(parent);
int children = rng.nextInt(3)+1;
for(int x=0; x<children;x++){
final NLevelItem childs = new NLevelItem(new SomeObject("Parent1 "+x),parent, new NLevelView() {
#Override
public View getView(NLevelItem item) {
View view = inflater.inflate(R.layout.list_item, null);
TextView tv = (TextView) view.findViewById(R.id.textView);
//tv.setBackgroundColor(Color.BLUE);
String name = (String) ((SomeObject) item.getWrappedObject()).getName();
tv.setText(name);
return view;
}
});
list.add(childs);
int grandChildren = rng.nextInt(5)+1;
for( int k = 0; k < grandChildren; k++) {
NLevelItem child = new NLevelItem(new SomeObject("child "+k),childs, new NLevelView() {
#Override
public View getView(NLevelItem item) {
View view = inflater.inflate(R.layout.check_list, null);
TextView tv = (TextView) view.findViewById(R.id.checktextView);
final String name = (String) ((SomeObject) item.getWrappedObject()).getName();
final CheckBox checkBox = (CheckBox)view.findViewById(R.id.check);
checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(selected != null){ //Edit
selected.setChecked(false);
}
selected = checkBox; //Edit
if(checkBox.isChecked()){
tempList.add((String) ((SomeObject)childs.getWrappedObject()).getName()+"+"+name);
}
else {
tempList.remove((String) ((SomeObject)childs.getWrappedObject()).getName()+"+"+name);
}
}
});
//tv.setBackgroundColor(Color.GRAY);
tv.setText(name);
return view;
}
});
list.add(child);
}
}
}
}
NLevelAdapter adapter = new NLevelAdapter(list);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
((NLevelAdapter)listView.getAdapter()).toggle(arg2);
((NLevelAdapter)listView.getAdapter()).getFilter().filter();
}
});
checkButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for (int i=0;i<tempList.size();i++){
Toast.makeText(context,tempList.get(i),Toast.LENGTH_LONG).show();
}
}
});
}
class SomeObject {
public String name;
public SomeObject(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
}
NLevelAdapter.java
public class NLevelAdapter extends BaseAdapter {
List<NLevelItem> list;
List<NLevelListItem> filtered;
public void setFiltered(ArrayList<NLevelListItem> filtered) {
this.filtered = filtered;
}
public NLevelAdapter(List<NLevelItem> list) {
this.list = list;
this.filtered = filterItems();
}
#Override
public int getCount() {
return filtered.size();
}
#Override
public NLevelListItem getItem(int arg0) {
return filtered.get(arg0);
}
#Override
public long getItemId(int arg0) {
return 0;
}
#Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
return getItem(arg0).getView();
}
public NLevelFilter getFilter() {
return new NLevelFilter();
}
class NLevelFilter {
public void filter() {
new AsyncFilter().execute();
}
class AsyncFilter extends AsyncTask<Void, Void, ArrayList<NLevelListItem> > {
#Override
protected ArrayList<NLevelListItem> doInBackground(Void...arg0) {
return (ArrayList<NLevelListItem>)filterItems();
}
#Override
protected void onPostExecute(ArrayList<NLevelListItem> result) {
setFiltered(result);
NLevelAdapter.this.notifyDataSetChanged();
}
}
}
public List<NLevelListItem> filterItems() {
List<NLevelListItem> tempfiltered = new ArrayList<NLevelListItem>();
OUTER: for (NLevelListItem item : list) {
//add expanded items and top level items
//if parent is null then its a top level item
if(item.getParent() == null) {
tempfiltered.add(item);
} else {
//go through each ancestor to make sure they are all expanded
NLevelListItem parent = item;
while ((parent = parent.getParent())!= null) {
if (!parent.isExpanded()) {
//one parent was not expanded
//skip the rest and continue the OUTER for loop
continue OUTER;
}
}
tempfiltered.add(item);
}
}
return tempfiltered;
}
public void toggle(int arg2) {
filtered.get(arg2).toggle();
}
}
Thanks in advance!!
i think you need to store the checkbox state in a boolean (is checked), and reflect that on the view, when getView() is called.
1- Add boolean checked to NLevelItem :
private boolean checked = false;
//add setter: setChecked(boolean)
//add getter isChecked()
2- Use that boolean in getView() (last one where checkbox is added)
#Override
public View getView(final NLevelItem item) {
// .......
final CheckBox checkBox = (CheckBox)view.findViewById(R.id.check);
checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//store checkbox state, note that NLevelItem item might need to be defined with 'final'
item.setChecked(checkBox.isChecked());
if(checkBox.isChecked()){
tempList.add((String) ((SomeObject)childs.getWrappedObject()).getName()+"+"+name);
}
else {
tempList.remove((String) ((SomeObject)childs.getWrappedObject()).getName()+"+"+name);
}
}//onClick()
}//setOnClickListener()
//update checkbox state from the corresponding NLevelItem
checkBox.setChecked(item.isChecked());
//.......
}//getView()
-EDIT:
to select 1 item, you need to iterate all items, set checked = false, but 1
i am not sure if you have to do it on:
List<NLevelItem> list;
or
List<NLevelListItem> filtered;
in the adapter class
private void selectOnly(int position){
for(int a=0;a<list.size();a++){
if(a == position){
list.get(a).setChecked(true);
continue;
}
list.get(a).setChecked(false);
}//for loop
notifyDataSetChanged(); // to update views (checkbox state)
}
Usage: selectOnly(15);
Use ViewHolder class to set and get Tag like this:
public class ListAdapter extends BaseAdapter {
private Context con;
private List<String> dataLt;
private static LayoutInflater inflater = null;
public ListAdapter(Context context, List<String> dataList){
con = context;
dataLt = dataList;
inflater = (LayoutInflater)con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return dataLt.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
ViewHolder holder;
if(convertView==null){
/****** Inflate tabitem.xml file for each row ( Defined below ) *******/
vi = inflater.inflate(R.layout.list_item_search, null);
/****** View Holder Object to contain tabitem.xml file elements ******/
holder = new ViewHolder();
holder.textView = (TextView) vi.findViewById(R.id.textView);
/************ Set holder with LayoutInflater ************/
vi.setTag( holder );
}
else
holder=(ViewHolder)vi.getTag();
return vi;
}
public static class ViewHolder{
TextView textView;
}
}
Hope this may help.

ListView doesn't want to refresh

I have one problem, I have one activity and one dialogfragment. When I click on button in my dialogfragment I send model to Activity and write this model to the list. But when I add to the list more than one element, my listview duplicate first element, I init my adapter in onCreate() and add new information in onExcerciseAdd:
Activity:
public class AddTrainingActivity extends ActionBarActivity implements ExcercisesFragment.onButtonAdd {
private ActionBarDrawerToggle toggle;
int DIALOG_TIME = 1;
int myHour = 00;
int myMinute = 00;
TextView tvTime;
Button btn_add_ex;
ListView list;
ExcerciseAdapter adapter;
ArrayList<ExcerciseModel> excercise_list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_addtraining);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
tvTime = (TextView) findViewById(R.id.tv_time_add);
tvTime.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showDialog(DIALOG_TIME);
}
});
btn_add_ex = (Button) findViewById(R.id.btn_add_exercise);
list = (ListView) findViewById(R.id.list_excercise);
excercise_list = new ArrayList<ExcerciseModel>();
Log.d("onCreate", "Work!");
adapter = new ExcerciseAdapter(excercise_list, this);
btn_add_ex.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ExcercisesFragment dlg = new ExcercisesFragment();
dlg.show(getSupportFragmentManager(),"dlg");
}
});
}
protected Dialog onCreateDialog(int id) {
if (id == DIALOG_TIME) {
Calendar c = Calendar.getInstance();
myHour = c.getTime().getHours();
myMinute = c.getTime().getMinutes();
TimePickerDialog tpd = new TimePickerDialog(this, myCallBack, myHour, myMinute, true);
return tpd;
}
return super.onCreateDialog(id);
}
TimePickerDialog.OnTimeSetListener myCallBack = new TimePickerDialog.OnTimeSetListener() {
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
myHour = hourOfDay;
myMinute = minute;
if (myMinute < 10) {
tvTime.setText(myHour + " : 0" + myMinute );
} else {
tvTime.setText(myHour + " : " + myMinute );
}
Log.d("TIME", "minutes " + myMinute);
}
};
#Override
public void onExcerciseAdd(ExcerciseModel model) {
Log.d("Adapter", "null? " + (adapter.isEmpty()));
excercise_list.add(model);
if (adapter.isEmpty()) {
runOnUiThread(new Runnable() {
#Override
public void run() {
adapter.notifyDataSetInvalidated();
adapter.notifyDataSetChanged();
list.invalidate();
list.invalidateViews();
}
});
}
list.setAdapter(adapter);
for (int i = 0; i < excercise_list.size(); i++){
Log.d("List_ex", "list(" + i +"): " + excercise_list.get(i).getTitle().toString());
}
}
}
Dialogfragment:
public class ExcercisesFragment extends DialogFragment {
private Button btn_add_dialog;
private EditText edit_time;
private EditText edit_count1;
private EditText edit_count2;
private EditText edit_weight;
private AutoCompleteTextView edit_ex;
public interface onButtonAdd {
void onExcerciseAdd (ExcerciseModel model);
}
onButtonAdd button_add;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
getDialog().setTitle("Title!");
View v = inflater.inflate(R.layout.fragment_add_excersise, null);
btn_add_dialog = (Button) v.findViewById(R.id.btn_add_exercise_fr);
edit_time = (EditText) v.findViewById(R.id.edit_ex_go);
edit_count1 = (EditText) v.findViewById(R.id.edit_podh);
edit_count2 = (EditText) v.findViewById(R.id.edit_repeat);
edit_weight = (EditText) v.findViewById(R.id.edit_weight_add);
edit_ex = (AutoCompleteTextView) v.findViewById(R.id.excercise_title);
button_add = (onButtonAdd) getActivity();
Resources res = getResources();
String[] excersices = res.getStringArray(R.array.excersices);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
R.layout.profile_item, R.id.item_autotext, excersices);
adapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
edit_ex.setAdapter(adapter);
edit_ex.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER) {
// Just ignore the [Enter] key
return true;
}
// Handle all other keys in the default way
return false;
}
});
edit_ex.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
edit_ex.showDropDown();
}
});
btn_add_dialog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String time = edit_time.getText().toString();
String title = edit_ex.getText().toString();
String weight = edit_weight.getText().toString();
String count1 = edit_count1.getText().toString();
String count2 = edit_count2.getText().toString();
if (title.equals("") || count1.equals("") || count2.equals("") || weight.equals("") || time.equals("")) {
Toast.makeText(getActivity(),"Необходимо заполнить все поля", Toast.LENGTH_SHORT).show();
} else {
ExcerciseModel model = new ExcerciseModel();
model.setTitle(edit_ex.getText().toString());
model.setTime(Integer.parseInt(edit_time.getText().toString()));
model.setPodh(Integer.parseInt(edit_count1.getText().toString()));
model.setCount(Integer.parseInt(edit_count2.getText().toString()));
model.setWeight(Integer.parseInt(edit_weight.getText().toString()));
button_add.onExcerciseAdd(model);
dismiss();
}
}
});
return v;
}
}
and Adapter:
public class ExcerciseAdapter extends BaseAdapter {
ArrayList<ExcerciseModel> list;
Activity context;
public ExcerciseAdapter (ArrayList<ExcerciseModel> list, Activity context) {
this.list = list;
this.context = context;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView txtViewTitle;
TextView txtViewTime;
TextView txtViewPodh;
TextView txtViewCount;
TextView txtViewWeight;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
LayoutInflater inflater = context.getLayoutInflater();
Log.d("ConvertView", "convertview is null " + (convertView == null));
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_item_ex, null);
holder = new ViewHolder();
holder.txtViewTitle = (TextView) convertView.findViewById(R.id.tv_adapter_title);
holder.txtViewTime = (TextView) convertView.findViewById(R.id.tv_adapter_time_get);
holder.txtViewPodh = (TextView) convertView.findViewById(R.id.tv_adapter_podh_get);
holder.txtViewCount = (TextView) convertView.findViewById(R.id.tv_adapter_count_get);
holder.txtViewWeight = (TextView) convertView.findViewById(R.id.tv_adapter_weight_get);
holder.txtViewTitle.setText(list.get(position).getTitle().toString());
holder.txtViewTime.setText(String.valueOf(list.get(position).getTime()));
holder.txtViewPodh.setText(String.valueOf(list.get(position).getPodh()));
holder.txtViewCount.setText(String.valueOf(list.get(position).getCount()));
holder.txtViewWeight.setText(String.valueOf(list.get(position).getWeight()));
} else {
holder = (ViewHolder) convertView.getTag();
}
Log.d("Adapter", "List_size = " +list.size());
Log.d("Adapter", "Title(" + position + "): " + list.get(position).getTitle().toString());
return convertView;
}
}
I don't know, but Adatper calls too many times, when I add one element it's calls 3 times. Please help me with this problem.
You only update your list items when you are creating them. You should do something like this:
LayoutInflater inflater = context.getLayoutInflater();
View view = (convertView == null)? inflater.inflate(R.layout.list_item_ex, parent, false) : convertView;
holder = new ViewHolder();
holder.txtViewTitle = (TextView) convertView.findViewById(R.id.tv_adapter_title);
holder.txtViewTime = (TextView) convertView.findViewById(R.id.tv_adapter_time_get);
holder.txtViewPodh = (TextView) convertView.findViewById(R.id.tv_adapter_podh_get);
holder.txtViewCount = (TextView) convertView.findViewById(R.id.tv_adapter_count_get);
holder.txtViewWeight = (TextView) convertView.findViewById(R.id.tv_adapter_weight_get);
holder.txtViewTitle.setText(list.get(position).getTitle().toString());
holder.txtViewTime.setText(String.valueOf(list.get(position).getTime()));
holder.txtViewPodh.setText(String.valueOf(list.get(position).getPodh()));
holder.txtViewCount.setText(String.valueOf(list.get(position).getCount()));
holder.txtViewWeight.setText(String.valueOf(list.get(position).getWeight()));
return view;
Also you don't need to call all of these methods when changing the data set
adapter.notifyDataSetInvalidated();
adapter.notifyDataSetChanged();
list.invalidate();
list.invalidateViews();
Calling adapter.notifyDataSetChanged(); should be enough
You also don't need to reset the adapter every time you change the data, so this line can also be removed
list.setAdapter(adapter);

Categories