I am trying to render news articles based on a few toggle buttons in a fragment. The articles show up when the correct button (allButton) is clicked, but don't disappear. Here is my code:
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_dashboard, container, false);
ToggleButton allButton = (ToggleButton) root.findViewById(R.id.allButton);
ToggleButton readButton = (ToggleButton) root.findViewById(R.id.readButton);
ToggleButton unreadButton = (ToggleButton) root.findViewById(R.id.unreadButton);
//TableLayout table = (TableLayout) root.findViewById(R.id.newsTable);
//showArticles(root, table, allButton, readButton, unreadButton);
allButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
//buttonView.setBackgroundColor(Color.WHITE);
buttonView.setTextColor(Color.BLACK);
unreadButton.setChecked(false);
allButton.setChecked(true);
readButton.setChecked(false);
TableLayout table = (TableLayout) root.findViewById(R.id.newsTable);
showArticles(root, table, allButton, readButton, unreadButton);
} else {
//buttonView.setBackgroundColor(Color.BLACK);
buttonView.setTextColor(Color.WHITE);
}
}
});
readButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
//buttonView.setBackgroundColor(Color.WHITE);
buttonView.setTextColor(Color.BLACK);
allButton.setChecked(false);
readButton.setChecked(true);
unreadButton.setChecked(false);
TableLayout table = (TableLayout) root.findViewById(R.id.newsTable);
showArticles(root, table, allButton, readButton, unreadButton);
} else {
//buttonView.setBackgroundColor(Color.BLACK);
buttonView.setTextColor(Color.WHITE);
}
}
});
unreadButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
//buttonView.setBackgroundColor(Color.WHITE);
buttonView.setTextColor(Color.BLACK);
allButton.setChecked(false);
unreadButton.setChecked(true);
readButton.setChecked(false);
TableLayout table = (TableLayout) root.findViewById(R.id.newsTable);
showArticles(root, table, allButton, readButton, unreadButton);
} else {
//buttonView.setBackgroundColor(Color.BLACK);
buttonView.setTextColor(Color.WHITE);
}
}
});
return root;
Please note that the showArticles edits the TableLayout passed directly. I thought that each time I called root.findViewById(), that the TableLayout would refresh to only the XML layout (disregarding programmatic additions), but it seems to keep the new tablerows added. Any help would be greatly appreciated! Thanks!
Related
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've got "for each" loop that creates textView for every obiect from the list and add them to the linear layout. It works great. Then I want to hide all of the textViews when user clicks on toggle button but here I've got problem - only the last textView from the list is being hidden , rest of them is still visible. I tried to solve this problem with many solutions ( for example with getChild()), but nothing works.
final List<FilterItem> filterItemList = filterData.getFilterItemList();
for (FilterItem filterItem : filterItemList) {
final TextView filter = new TextView(MainPanelActivity.this);
filter.setText(filterItem.getFilterItemName());
filter.setTextColor(R.color.black);
linearLayout.addView(filter);
filter.setVisibility(View.GONE);
textLine.setOnCheckedChangeListener(
new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
filter.setVisibility(View.VISIBLE);
} else {
filter.setVisibility(View.GONE);
}
}
});
Note that youre setting a listener for textLine inside the for loop - so for each iteration you set a new listener that changes the visibility of the TextView created in the current iteraton.
Move textLine.setOnCheckedChangeListener() outside of the for loop; and inside onCheckedChanged - loop through all children of linearLayout and set the visibility for each child.
textLine.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
for (View v : linearLayout.getChildren()) {
if (v instanceof TextView) {
if (isChecked) {
v.setVisibility(View.VISIBLE);
} else {
v.setVisibility(View.GONE);
}
}
}
You could keep a list of TextViews when you create them. Then set the click listener outside the for-loop as Dmitri says, which would iterate through the list of TextViews and set the visibility to GONE.
private void setup() {
List<View> textViews = new ArrayList<>();
for (FilterItem filterItem : filterData.getFilterItemList()) {
View view = createTextViewFor(filterItem);
linearLayout.addView(filter);
textViews.add(view);
}
updateVisibility(textViews, View.GONE);
textLine.setOnCheckedChangeListener(
new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int visibility = isChecked ? View.VISIBLE : View.GONE;
updateVisibility(textViews, visibility);
}
}
);
}
private View createTextViewFor(FilterItem filterItem) {
TextView view = new TextView(MainPanelActivity.this);
view.setText(filterItem.getFilterItemName());
view.setTextColor(R.color.black);
view.addFilter(filterItem);
return view;
}
private void updateVisibility(List<View> views, int visibility) {
for (View view : views) {
view.setVisibility(visibility);
}
}
In case you want to display textView dynamically, I think putting textView inside RecyclerView will be a better idea. RecyclerView has its own Adapter which will make it easy to play with data and textViews. Give recyclerView a try. RecycerView for what you are trying to do can be learnt in few hours and sky is the limit for what you can do with recyclerView :)
I want to delete selected rows from a todo list by clicking on the checkbox and deleting them trough the delete button, for that I am within my custom adapter setting a setOnCheckedChangeListener on my checkbox and setOnClickListener on my delete button, now keep in mind that the delete button is inflated on my fragment view and I am using it on my row view, but the problem is only the last element from my todo list is getting deleted not the rest of them, I tried working within the fragment view and notify the adapter later on but all I got was a null pointer error on my checkbox.
Row View:
todoCheckBox = (CheckBox) convertView.findViewById(R.id.todo_CheckBox);
todoTextView.setText(values.get(position));
todoCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//Toast.makeText(getContext(), " CheckBox Status: " + isChecked, Toast.LENGTH_LONG).show();
mDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mDelete.isPressed() && (todoCheckBox.isChecked())) {
//convertView.clearFocus(position);
mAdapter.clear();
//mAdapter.notifyDataSetChanged();
}
}
});
}
});
Fragment View:
#TargetApi(9) // remember this for isEmpty()
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_todo, container, false);
ArrayList<String> todoList = new ArrayList<String>();
mAdapter = new UsersAdapter(getActivity(), todoList);
listViewToDo = (ListView) v.findViewById (android.R.id.list);
listViewToDo.setAdapter(mAdapter);
mToDoField = (EditText) v.findViewById(R.id.todo_editText);
mDelete = (Button) v.findViewById(R.id.delete_button);
mAdd = (Button)v.findViewById(R.id.add_button);
mAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String toDo = mToDoField.getText().toString().trim();
if (toDo.isEmpty()){
return;
}
mAdapter.add(toDo);
mToDoField.setText("");
}
});
return v;
}
}
You need to assign an onclick listener to your delete button outside of the onChecked statement. Add it in code just after you assign the onClick event to the add button. This is because a view in android can only have 1 listener per event type.
The onClick event can look something like below using a sparese
mDelete.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
SparseBooleanArray checked = listViewToDo.getCheckedItemPositions();
for (int i = 0; i < listViewToDo.getCount(); i++){
if (checked.get(i)==true)
{
mAdapter.remove(i);
}
mAdapter.notifyDataSetChanged();
}
listViewToDo.clearChoices();
}
});
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();
}
}
};