Can Anybody help me? checkbox can't create dynamically . Just like sometimes I use the program create 6 checkboxes. Sometimes I create 8 checkboxes. I want to set each checkbox a event to catch the time when it's checked.In the following way, I get an error:Cannot refer to a non-final variable i inside an inner class defined in a different method.Change modifier of "i" to final.
The mCheckTime is a long array.
for(int i=0;i<optionsNum;i++){
mCheckBox[i]=new CheckBox(this);
mCheckBox[i].setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener(){
public void onCheckedChanged(CompoundButton buttonView, boolean isCheck){
if (mCheckBox[i].isChecked()) {
mCheckTime[i] = System.currentTimeMillis();
}
}
};
if your content view is LinearLayout, try
final CheckBox mCheckBox = new CheckBox(this);
mCheckBox
.setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isCheck) {
if (mCheckBox.isChecked()) {
mCheckBox.setText(System.currentTimeMillis() + "");
}
}
});
LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
addContentView(mCheckBox, params);
======EDIT======
or try this
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
setContentView(layout);
CheckBox[] mCheckBox = new CheckBox[6];
for (int i = 0; i < 6; i++) {
mCheckBox[i] = new CheckBox(this);
mCheckBox[i].setText(i + "");
mCheckBox[i]
.setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isCheck) {
if (isCheck) {
Toast.makeText(MainActivity.this,
System.currentTimeMillis() + "",
Toast.LENGTH_SHORT).show();
}
}
});
layout.addView(mCheckBox[i]);
}
Thank you very much. I use a final variable j to replace i inside the inner class.
for(int i=0;i<optionsNum;i++){
final int j = i;
mCheckBox[i]=new CheckBox(this);
mCheckBox[i].setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener(){
public void onCheckedChanged(CompoundButton buttonView, boolean isCheck){
if (mCheckBox[i].isChecked()) {
mCheckTime[i] = System.currentTimeMillis();
}
}
};
Related
I have many similar cases, when I reach to the end and return back then my options of radiogroup and checkboxes adds one more instance of it.
eg;
radio button options before scrolling "
option1
option 2 " after scrolling I have "option1 option2 option1 option2 " and so on..
#Override
public void onBindViewHolder(final MyHolder holder, final int position) {
final MyData mData = dataList.get(position);
switch (holder.getItemViewType()) {
case 1:
holder.textView0.setText(mData.getText());
final int radioCount = mData.getTextFields().size();
for (int i = 0; i < radioCount; i++) {
RadioButton radio = new RadioButton(context);
radio.setId(View.generateViewId());
radio.setText(mData.getTextFields().get(i).getName());
holder.radioGroup.addView(radio);
radio.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
//do something
}
});
}
break;
case 2: holder.textView1.setText(mData.getText());
List<Object> selectList1= new ArrayList<>() ;
int Option_Count = mData.getTextFields().size();
for (int i = 0; i < Option_Count; i++) {
final TableRow row = new TableRow(context);
row.setId(i);
row.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
CheckBox checkBox = new CheckBox(context);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
String joined="";
if (b) {
selectList1.add((String) compoundButton.getText());
joined = TextUtils.join(", ", selectList1);
} else {
selectList1.remove((String) compoundButton.getText());
joined = TextUtils.join(", ", selectList1);
}
if(b){
} }
});
checkBox.setId(i);
checkBox.setText(mData.getTextFields().get(i).getLabel());
row.addView(checkBox);
holder.linearLayout1.addView(row);
}
break;
}
}
This is a standard behaviour of the RecyclerView. Holders are reusable, when user scrolls, the onBindViewHolder() is called and radio buttons are added again.
The question is, how to make it right? You can initialize your views in onCreateViewHolder(). Is it possible for you? I don't know your data model. For example, you can add your radio buttons etc. in each constructor of your custom Viewholder class.
I know that this question has been asked over and over again but still I haven't found/understand anything that I found. The checkbox is unchecked whenever the list is scrolled down or some of the checkbox is checked whenever the list is scrolled up.
Here is my code:
#Override
public View getView(final int position, View view, ViewGroup viewGroup) {
//View v = View.inflate(mContext, R.layout.sales_invoice_custom,null);
final ViewHolder holder;
if (view == null) {
view = View.inflate(mContext, R.layout.sales_invoice_custom, null);
holder = new ViewHolder();
holder.SelectInvoiceCB = (CheckBox) view.findViewById(R.id.selectInvoiceCB);
holder.SalesInvoiceNo = (TextView) view.findViewById(R.id.SINo);
holder.InvoiceDate = (TextView) view.findViewById(R.id.SIDate);
holder.InvoiceAmount = (TextView) view.findViewById(R.id.SIAmount);
holder.AmountDue = (TextView) view.findViewById(R.id.SIAmountDue);
holder.DueDate = (TextView) view.findViewById(R.id.SIdueDate);
holder.PayFull = (CheckBox) view.findViewById(R.id.SIFull);
holder.PayPartial = (CheckBox) view.findViewById(R.id.SIPartial);
holder.TotalAmount = (EditText) view.findViewById(R.id.SITotalAmount);
holder.CreditMemoID = (TextView) view.findViewById(R.id.creditMemoID);
holder.CreditMemoDate = (TextView) view.findViewById(R.id.creditMemoDate);
holder.CreditMemoReason = (TextView) view.findViewById(R.id.creditMemoReason);
holder.LL2 = (LinearLayout) view.findViewById(R.id.ll2);
holder.LL3 = (LinearLayout) view.findViewById(R.id.ll3);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
InvoicePopulate(holder,position);
return view;
}
public void InvoicePopulate(final ViewHolder holder, final int position) {
dbHelper = new DBHelper(mContext);
Calendar c = Calendar.getInstance();
SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd");
final String formattedDate = df1.format(c.getTime());
//holder.SelectInvoiceCB.setChecked(false);
holder.SalesInvoiceNo.setText(invoiceLists.get(position).getSales_Invoice_ID());
holder.InvoiceDate.setText(invoiceLists.get(position).getInvoice_Date());
holder.DueDate.setText(invoiceLists.get(position).getDue_Date());
float invAmount = 0;
invAmount = Math.round(Float.parseFloat(invoiceLists.get(position).getInvoice_Amount())*100.00)/(float)100.00;
holder.InvoiceAmount.setText(String.format("%,.2f",invAmount));
holder.AmountDue.setText(String.format("%,.2f",invAmount));
try {
if (invoiceLists.get(position).getAmount_Paid().toString().equals("") ||
invoiceLists.get(position).getAmount_Paid().toString().equals("0")) {
invAmount = 0;
invAmountDue = 0;
invAmountPaid = 0;
invAmount = Math.round(Float.parseFloat(invoiceLists.get(position).getInvoice_Amount())*100.00)/(float)100.00;
invAmountDue = invAmount - invAmountPaid;
Log.e("Without AmountPaid ", "Amount Due : " + String.valueOf(invAmountDue));
} else {
invAmount = 0;
invAmountDue = 0;
invAmountPaid = Math.round(Float.parseFloat(invoiceLists.get(position).getAmount_Paid())*100.00)/(float)100.00;
invAmount = Math.round(Float.parseFloat(invoiceLists.get(position).getInvoice_Amount())*100.00)/(float)100.00;
invAmountDue = invAmount - invAmountPaid;
Log.e("With AmountPaid ", "Amount Due : " + String.valueOf(invAmountDue));
}
final float finalInvAmount = invAmountDue;
holder.PayFull.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (holder.PayFull.isChecked()) {
holder.PayPartial.setChecked(false);
if (holder.SelectInvoiceCB.isChecked()) {
invoiceStatusValue = "PAID_FULL";
holder.TotalAmount.setText(String.valueOf(Math.round(finalInvAmount*100.00)/100.00));
//holder.TotalAmount.setText(holder.InvoiceAmount.getText().toString());
}
}
}
});
holder.PayPartial.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (holder.PayPartial.isChecked()) {
holder.PayFull.setChecked(false);
if (holder.SelectInvoiceCB.isChecked()) {
invoiceStatusValue = "PAID_PARTIAL";
holder.TotalAmount.setText("0.00");
}
}
}
});
holder.AmountDue.setText(String.format("%,.2f",invAmountDue));
} catch (Exception e) {
e.getMessage();
}
if (TotalPaymentAmount >= Float.parseFloat(String.valueOf(invAmountDue))) {
holder.SelectInvoiceCB.setChecked(true);
holder.PayFull.setChecked(true);
holder.PayFull.setClickable(true);
holder.PayPartial.setClickable(true);
holder.TotalAmount.setText(String.valueOf(Math.round(invAmountDue*100.00)/100.00));
}
}
} catch (Exception e){
e.getMessage();
System.out.println("Error - " + e);
} finally {
dbHelper.close();
}
}
You should store the checkbox is checked or not in your viewmodel class.Ex. boolean isChecked; than in getView() set the checkbox from viewmodel ischecked.
You have to manage checked state in model class. In your case you have to manage three booleans for PayFull, PayPartial and SelectInvoiceCB checkbox checked state.
When you done setChecked at that time update the model class checked behaviour like:
class YourModel{
public boolean isPayFull, isPayPartial, isSelectInvoice;
}
//This will update UI from model check behaviour
holder.PayFull.setChecked(invoiceLists.get(position).isPayFull);
holder.PayPartial.setChecked(invoiceLists.get(position).isPayPartial);
holder.SelectInvoiceCB.setChecked(invoiceLists.get(position).isSelectInvoice);
holder.PayFull.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (holder.PayFull.isChecked()) {
holder.PayPartial.setChecked(false);
if (holder.SelectInvoiceCB.isChecked()) {
invoiceStatusValue = "PAID_FULL";
}
}
//This is to manage the state of checkbox in model
invoiceLists.get(position).isPayFull = holder.PayFull.isChecked();
invoiceLists.get(position).isPayPartial= holder.PayPartial.isChecked();
invoiceLists.get(position).isSelectInvoice= holder.SelectInvoiceCB.isChecked();
}
});
holder.PayPartial.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (holder.PayPartial.isChecked()) {
holder.PayFull.setChecked(false);
if (holder.SelectInvoiceCB.isChecked()) {
invoiceStatusValue = "PAID_PARTIAL";
holder.TotalAmount.setText("0.00");
}
}
//This is to manage the state of checkbox in model
invoiceLists.get(position).isPayFull = holder.PayFull.isChecked();
invoiceLists.get(position).isPayPartial= holder.PayPartial.isChecked();
invoiceLists.get(position).isSelectInvoice= holder.SelectInvoiceCB.isChecked();
}
});
Generally, I prefer to do click events on checkbox rather than checked change listeners in list item, checked change will get call on scroll and update the UI on every scroll so better to appy click event on checkbox and manage checked state from model class as I mentioned you.
In Answer to your Question , the reason it's checking and unchecking lies in this piece of your code in all the CheckChangedListeners
if (holder.PayFull.isChecked()) {
holder.PayPartial.setChecked(false);
You are unchecking the check box as soon as its checked.
On a separate note you need to handle the checked states during view recycling.
Other wise the check boxes will not maintain the proper states. when scrolling.
One choice is to save the states in the ArrayList along with your data. Keep 3 boolean variables state1,state2,state3 for the check boxes.
In the InvoicePopulate(...) method -
holder.PayFull.setChecked(invoiceLists.get(position).getState1())
In the check changed listener add following line
invoicelists.get(position).setState1(isChecked)
Here is the code for my check box.
if (type.equalsIgnoreCase("checkbox")){
String checkBoxText = dataObj.getString("checkboxname");
checkBox = dynamicviews.CreateCheckbox(context,value,checkBoxText);
id = R.id.gl + i + 9;
if (j == 2) {
j = 0;
tableRow = new TableRow(context);
tableRow.setPadding(0, 10, 0, 10);
tableLayout.addView(tableRow);
}
j++;
tableRow.addView(checkBox);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
String string = checkBox.getText().toString();
Log.i("checkbox",string);
}
});
}
and below code is for creating checkbox
public CheckBox CreateCheckbox(Context context,String checkName,String checkBoxText){
checkBox = new CheckBox(context);
checkBox.setGravity(Gravity.CENTER);
checkBox.setTextAlignment(Gravity.CENTER);
checkBox.setText(checkBoxText);
checkBox.setTextColor(Color.WHITE);
checkBox.setBackgroundResource(R.drawable.custom_rdbtn);
checkBox.setButtonDrawable(new StateListDrawable());
checkBox.setCompoundDrawablePadding(10);
return checkBox;
}
and problem is am getting the value of last created checkbox for each one.
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
String string = buttonView.getText().toString();
Log.i("checkbox",string);
}
});
i got the solution
You are adding the checkBoxobject to the tableRow BEFORE you set its setOnCheckedChangeListener - so it will only work for the last checkBox you've created.
To solve this, you simply need to do set the setOnCheckedChangeListener first, and then call the tableRow.addView(checkBox) - see the code below:
//first, set the setOnCheckedChangeListener on this checkBox,
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{ String string = buttonView.getText().toString();
Log.i("checkbox",string);
}
});
//only now do you add the view
tableRow.addView(checkBox);
Give it a try, I hope it helps.
I am dynamically generating checkboxes in my program like so:
public void addNewItem(String item, TableLayout tablel) {
TableRow row = new TableRow(this);
TableRow.LayoutParams params = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT);
row.setLayoutParams(params);
CheckBox item1 = new CheckBox(this);
item1.setText(item);
row.addView(item1);
tablel.addView(row, i);
i++;
From what I've been able to test, this work fine for adding checkboxes to my table. The problem I'm encountering is that I want to be able to have something happen when a checkbox is checked, which I am unsure of how to do without knowning the id. Is there some way to get around this or get the id of the checkbox that has been checked when the onCheckBoxClick() method is called?
You don't need to know the ID because you already have the checkbox as on object.
Use this:
item1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(item1.isChecked()){
System.out.println("Checked");
}else{
System.out.println("Un-Checked");
}
}
});
An other possibility:
item1.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if ( isChecked )
{
// perform logic
}
}
});
Assign id via code (programmatically)
1.Manually set ids using someView.setId(int);
2.The int must be positive, but is otherwise arbitrary.
Then you can access that id.
It think this would help you.
You have created TableRow and CheckBox you should set id pragmatically like this
public void addNewItem(String item, TableLayout tablel) {
TableRow row = new TableRow(this);
row.setId(i);//i is a positive int value
TableRow.LayoutParams params = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT);
row.setLayoutParams(params);
CheckBox item1 = new CheckBox(this);
row.setId(j);//j is a positive int value
item1.setText(item);
row.addView(item1);
tablel.addView(row, i);
i++;
You can check this SO question
int chkBoxId = 10;
int tableRowId = 100;
String texts[] = {"Text1", "Text2", "Text3", "Text4", "Text5"};
CheckBox[] chkBoxes;
private TableLayout tableLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dynamic_chk_box);
tableLayout = (TableLayout) findViewById(R.id.tableLayout);
chkBoxes = new CheckBox[texts.length];
for(int i = 0; i < 5; i++) {
TableRow row = new TableRow(this);
TableRow.LayoutParams params = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT);
row.setLayoutParams(params);
chkBoxes[i] = new CheckBox(this);
chkBoxes[i].setId(chkBoxId++);
row.setId(tableRowId);//tableRowId is a positive int value
chkBoxes[i].setText(texts[i]);
row.addView(chkBoxes[i]);
tableLayout.addView(row, i);
tableRowId++;
}
for (int i = 0; i < texts.length; i++) {
final int j = i;
chkBoxes[j].setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
if(isChecked) {
int checkedId = chkBoxes[j].getId();
Toast.makeText(DynamicCheckBoxActivity.this,
String.valueOf(checkedId),
Toast.LENGTH_SHORT).show();
} else {
int unCheckedId = chkBoxes[j].getId();
System.out.println("Uncheck ===> " + String.valueOf(unCheckedId));
}
}
});
}
}
I'm adding a checkbox in my application dynamically, and I want to delete the records which are checked. But, I'm not getting the ID of the checkbox. How can I do this?
Code:
package com.my.StudentInfoManagement;
public class ListData extends Activity{
DataHelper dh;
TableLayout tb;
CheckBox[] ch=new CheckBox[50];
EditText ed;
int a[]=new int[50];
int k=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.listdataxml);
dh=new DataHelper(this);
System.out.println("in list data");
List<String> names= this.dh.selectAll();
ed=(EditText) findViewById(R.id.ed_id);
tb=(TableLayout) findViewById(R.id.table);
int i,j=1;
TextView name1 = null,id,dob,gender,branch,email,address,mobile;
String name11,id1 = null,dob1,gender1,branch1,email1,address1,mobile1;
TableRow tr=new TableRow(this);
tr.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
TextView tv=new TextView(this);
String c = null;
String data[]=new String[50];
int cnt=0;
for(String name:names)
{
if((!name.equals("-999")))
{
data[cnt]=name;
cnt++;
System.out.println("........."+name);
}
else
{
cnt=0;
name1=new TextView(this);
name1.setText(data[1]+" ");
id=new TextView(this);
id.setText(data[0]+" ");
System.out.println("ID is...."+data[0]);
dob=new TextView(this);
dob.setText(data[3]+" ");
gender=new TextView(this);
gender.setText(data[2]+" ");
branch=new TextView(this);
branch.setText(data[4]+" ");
mobile=new TextView(this);
mobile.setText(data[5]+" ");
email=new TextView(this);
email.setText(data[6]+" ");
address=new TextView(this);
address.setText(data[7]+" ");
tr=new TableRow(this);
tr.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
ch[k]=new CheckBox(this);
System.out.println("sysout");
i=Integer.parseInt(data[0]);
ch[k].setId(i);
tr.addView(ch[k]);
a[k++]=i;
tr.addView(id);
tr.addView(name1);
tr.addView(dob);
tr.addView(gender);
tr.addView(branch);
tr.addView(mobile);
tr.addView(email);
tr.addView(address);
tb.addView(tr,new TableLayout.LayoutParams( LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
j++;
System.out.println("count"+j);
}
}
}
public void delete(View v){
System.out.println("In delete");
int bb=k,id ;
for (int i=0; i <k; i++)
{
final int j = a[i];
System.out.println("in for loop"+j);
ch[j].setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
System.out.println("Checked ID :: " + ch[j].getId());
}
});
}
System.out.println("00000000000000000..."+id);
dh.deleteData(id);
}
}
strong textJust take a global variable
int chkId = 1001;
then at time of adding CheckBox dynamically, set its id as
ch.setId(++chkId);
then at time of deleting CheckBox, you can get id of Checked CheckBox simple by using
getId()
methhod
See Following Demo:
public class ChkBoxesActivity extends Activity {
int chId = 1000;
int chPos = -1;
LinearLayout ll;
String[] names = {"Tom", "Dick", "Keanu", "Harry", "Katrina", "Peter", "Julia", "Emma"};
CheckBox[] ch;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ll = (LinearLayout) findViewById(R.id.ll);
ch = new CheckBox[names.length];
for(int i=0; i<names.length; i++) {
ch[i] = new CheckBox(this);
ch[i].setId(chId++);
System.out.println("CHID :: "+chId);
System.out.println("I :: "+i);
ch[i].setText(names[i]);
ll.addView(ch[i]);
}
for (int i = 0; i < names.length; i++) {
final int j = i;
ch[j].setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
System.out.println("Checked ID :: " + ch[j].getId());
}
});
}
}
}
Views added dynamically do not have an ID until you specifically set them. So you need to call view.setId() on the view when you're adding to your layout, else you won't be able to reference it with view.getId().
I experienced a similar issue a while back when trying to dynamically create a RelativeLayout and positions the inner views relative to each other; they wouldn't align how they should have because the ID's didn't exist until I explicitly set one for them.
Also, why are you doing this:
ch.getId();
ch.setId(1);
That makes absolutely no sense. Take it out.
And also, you're going to need a reference linking the CheckBox to the View you want to delete. In this case, I would make a new ArrayList of Objects that have both a CheckBox and a View inside of it, IE.
public Class MyRow{
CheckBox c;
View v;
public MyRow() { }
}
Then when adding your views dynamically, add them to your MyRow or whatever class, then add that class to an ArrayList, and boom, you now have references between them and can remove the correct ones.