Checkbox's state not properly shown when `performClick` is used - android

I got a tricky problem here:
in my app, there's a list (using a ListView) and each item contains text and a checkbox aligned to the right hand side.
Now, clicking the checkbox itself works, I installed a handler (OnClickListener) for it and perform an internal action. The visible state of the checkbox is just as expected - clicked the first time the tick is there, clicked again the tick disappears.
Now I simply wanted to "extend" the clickable area to the complete list entry - my approach was to install an OnItemClickListener using ListView.setOnItemClickListener() and within this listener I do the following:
resultView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
CheckBox checkBox = (CheckBox) view.findViewById(R.id.checkbox);
checkBox.performClick();
}
});
That sounds simple, but what happens is that sometimes (not every time) the tick in the checkbox does not appear after that! I added a checkBox.invalidate() but that did not help.
How can I have a checkbox "react" to the click of the complete list entry item???
Thanks!

Rather than use performClick() use checkBox.setChecked( !checkBox.getChecked() ); instead. performClick() will cause the onClickListener to be called again potentially causing a recursion, which could explain the odd behaviour that you're seeing.

#Override
public void onItemClick(AdapterView<?> arg0, View v, int position, long arg3) {
// TODO Auto-generated method stub
CheckBox cb = (CheckBox) v.findViewById(R.id.chkSelected);
TextView tv = (TextView) v.findViewById(R.id.tvName);
// pi = (PackageInfo) arg0.getItemAtPosition(position);
cb.performClick();
if (cb.isChecked()) {
checkedValue.add(tv.getText().toString());
} else if (!cb.isChecked()) {
checkedValue.remove(tv.getText().toString());
}
}

Related

disabled checkboxes get enabled radomly after recycling view through the adapter in android app

i have the following problem. i have set three checkboxes in my app in a way so when i check one of them the other two get disabled. the problem is that when i scroll up or down namely when the views get recycled some of the disabled checkboxes get enabled which of course i dont want to happen. could you please help me to solve that problem?
the code in the adapter is this :
#NonNull
#Override
public View getView(final int position1, View convertView1, ViewGroup parent1) {
View listItemView1 = convertView1;
if (listItemView1 == null) {
listItemView1 = LayoutInflater.from(getContext()).inflate(R.layout.list_item1, parent1, false);
}
final ColorQuiz currentColorQuiz = getItem(position1);
TextView questionTextView = (TextView) listItemView1.findViewById(question_text_view);
questionTextView.setText(currentColorQuiz.getQuestionHeader());
final CheckBox box1 = (CheckBox) listItemView1.findViewById(R.id.check_Box_view1);
box1.setText(currentColorQuiz.getCheckBoxTextA());
final CheckBox box2 = (CheckBox) listItemView1.findViewById(R.id.check_Box_view2);
box2.setText(currentColorQuiz.getCheckBoxTextB());
final CheckBox box3 = (CheckBox) listItemView1.findViewById(R.id.check_Box_view3);
box3.setText(currentColorQuiz.getCheckBoxTextC());
box1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (box1.isChecked() ) {
thesisA[position1]=true;
box2.setEnabled(false);
box3.setEnabled(false);
} else {
thesisA[position1]=false;
box2.setEnabled(true);
box3.setEnabled(true);
}
int getPositionA = (Integer) compoundButton.getTag(); // Here we get the position that we have set for the checkbox using setTag.
colorQuizs.get(getPositionA).setSelectedA(compoundButton.isChecked());
}
});
box1.setTag(position1);
box1.setChecked(colorQuizs.get(position1).isSelectedA());
.
.
.
and continues the same way with the next two checkboxes (box2, box3).
maybe while you calling box1.setChecked then one of the old listeners is called and it is causing problems (as it still has old tag, and propably setting wrong data to your model ).
Try to add at the beggining to make sure that something wrong does not happen:
box1.setOnCheckedChangeListener(null);
box2.setOnCheckedChangeListener(null);
box3.setOnCheckedChangeListener(null);
This will tell you if not calling callback while property does not change is reason of this problem:
box1.setChecked(!colorQuizs.get(position1).isSelectedA());
box1.setChecked(colorQuizs.get(position1).isSelectedA());

Android: If statement based on checkbox not being checked

I think this is really easy but I am fairly new to android development so thanks in advance
If the first one is checked I generate a random number for text Item 1. If both the checkboxs are checked I generate text for the second text. I was wondering what is the most efficient way to do this
Here is the snippet that I need help with
if(edit1.isChecked()){
text1.setText(String1[randomInt]);
}
if(edit1.isChecked() && edit2.isChecked()){
text2.setText(String1[randomInt]);
}
Obviously, the first statement will show true in both. basically is there a way to say if edit2 is false?
Try this:
edit2.isChecked()=false;
if(edit1.isChecked() && (edit2.isChecked()==false)) {
text2.setText(String1[randomInt]);
}
#Override
public void onItemClick(AdapterView<?> arg0, View v, int position, long arg3) {
// TODO Auto-generated method stub
CheckBox cb = (CheckBox) v.findViewById(R.id.chkSelected);
TextView tv = (TextView) v.findViewById(R.id.tvName);
// pi = (PackageInfo) arg0.getItemAtPosition(position);
cb.performClick();
if (cb.isChecked()) {
studentList.add(tv.getText().toString());
} else if (!cb.isChecked()) {
studentList.remove(tv.getText().toString());
}
}

setting text in Gallery onItemSelected causes scrolling to snap

In the galleryView onItemSelected I call setText that change the text for a textview thats part of the main layout:
#Override
public void onItemSelected(EcoGalleryAdapterView<?> parent, View view, int position, long id) {
// --- run asyncTask to update gallery view here
TextView myTextView = (TextView) findViewById(R.id.myTextView);
myTextView.setText("position is: ": position);
}
if I left everything as it is and just removed myTextView.setText the gallery works as expected but if I kept it then when scrolling the gallery snaps to the selected position really fast in an ugly way. What could be the issue?
"Ugly" is a pretty subjective term for describing a user interface transition.
However, it sounds as though what you want is a custom animation when an item is selected. onItemSelected() is called before the layout happens, so you can animate your Gallery or individual Views however you want in this method.
I would suggest reading the Animation and Graphics documentation from the Android developer documentation to more fully understand animations and to help decide what you actually want.
The code will vary depending on what you decide you want it to look like and what version of Android you are targeting. A simple View animation that will fade the selected view in might look something like this:
public void onItemSelected(EcoGalleryAdapterView<?> parent, View view,
int position, long id) {
view.setAnimation(new AlphaAnimation(0, 1));
}
// try this
TextView myTextView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.image_full);
myTextView = (TextView) findViewById(R.id.myTextView);
}
#Override
public void onItemSelected(EcoGalleryAdapterView<?> parent, View view, int position, long id) {
// --- run asyncTask to update gallery view here
myTextView.setText("position is :"+ position);
myTextView.invalidate();
}
The setText commands sits on the UI Thread, maybe it's taking a higher priority or something from the current Gallery animation which disrupts it from acting as it should.
try setting your setText inside a handler:
new Handler().post(new Runnable() {
#Override
public void run() {
myTextView.setText("position is: ": position);
}
});

How to enable button after using spinner

I am creating a program that has the mainMenuButton button (created in onCreate) disabled by default.
The user first has to check a few boxes and select something from the spinner before the mainMenuButton button becomes enabled. Currently, I can't even get the button to enable after using the spinner.
I've tried both
#Override
public void onClick(View v)
{
switch(v.getId())
{
case R.id.main_menu_button:
openMainMenu();
break;
case R.id.building_spinner:
Button mainMenuButton=(Button)findViewById(R.id.main_menu_button);
mainMenuButton.setEnabled(true);
break;
}
}
and
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
View mainMenuButton=(View)findViewById(R.id.main_menu_button);
mainMenuButton.setEnabled(true);
}
but to no avail. I've also tried replacing View with Button, but that didn't enable the mainMenuButton either. What exactly am I supposed to do to enable the button after something on the spinner has been selected?
Also, would there be much of a big difference to implement it for checkboxes as well?
EDIT2 :
If I comment out the if and else statement, the button remains permanently disabled. If I leave as is, the button is never disabled to begin with and never disables, which I don't understand because I haven't even touched the spinner, so it should be disabled by default.
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
String buildingString = parent.getItemAtPosition(position).toString();
if(buildingString !="Select Building")
{
Button mainMenuButton=(Button)findViewById(R.id.main_menu_button);
mainMenuButton.setEnabled(true);
}
else
{
Button mainMenuButton=(Button)findViewById(R.id.main_menu_button);
mainMenuButton.setEnabled(false);
}
}
Im not sure if this affects it, but the spinner strings was formatted like this :
<string-array name="building_array">
<item>Select Building</item>
You've not registered a listener on spinner.
Add this in your onCreate
spinner.setOnItemSelectedListener(this);
and then write you code in onItemSelected.

Android - Make ImageView Visible When ListItem is selected

I have a listview and each item has a title, some info, and a couple ImageViews I'm using as edit/delete buttons. I don't want to show these "buttons" unless the user selects the row. I can make the "buttons" invisible using:
DeleteButton.setVisibility(View.INVISIBLE);
EditButton.setVisibility(View.INVISIBLE);
in my BindView.
I can make the buttons visible in an onListItemClick:
ImageView DeleteButton = (ImageView) v.findViewById(R.id.button_delete);
ImageView EditButton = (ImageView) v.findViewById(R.id.button_edit);
DeleteButton.setVisibility(View.VISIBLE);
EditButton.setVisibility(View.VISIBLE);
What I can't do is make the "buttons" invisible when selecting another item or scrolling away.
The closest I found was to do a loop through the listitems in the current view and set them all to invisible before making the selected one visible:
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
\\loop through all the items and set them back to invisible
for (int i=0;i<=l.getLastVisiblePosition();i++){
View vChild = l.getChildAt(i);
ImageView DeleteButton = (ImageView) vChild.findViewById(R.id.button_delete);
ImageView EditButton = (ImageView) vChild.findViewById(R.id.button_edit);
DeleteButton.setVisibility(View.INVISIBLE);
EditButton.setVisibility(View.INVISIBLE);
}
\\set the selected one visible
ImageView DeleteButton = (ImageView) v.findViewById(R.id.button_delete);
ImageView EditButton = (ImageView) v.findViewById(R.id.button_edit);
DeleteButton.setVisibility(View.VISIBLE);
EditButton.setVisibility(View.VISIBLE);
}
As you can guess...this approach only works if you have a few items.
I thought about adding a field to the SQLite database my list is using to keep track of the button visibility (similar to what you do for checkboxes) but that seemed silly. Please tell me there's another way.
Another way to do this would be to have an int field in your class that will remember the current position:
private int current = -1;
then in the onItemCLick() method use that field to hide/show your views:
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// if it is the first click ignore this part
if (current != -1) {
View last = l.getChildAt(current); // the last one clicked
last.findViewById(R.id.button1).setVisibility(View.GONE); // kill it
}
v.findViewById(R.id.button1).setVisibility(View.VISIBLE);
current = position; // remember the new clicked position
}
If you want the views to be gone also when you scroll the list and those views aren't visible then in the bindView() method add the lines that hide the views:
//...
ImageView DeleteButton = (ImageView) view.findViewById(R.id.button_delete); // view is the view that you get as a parameter
ImageView EditButton = (ImageView) view.findViewById(R.id.button_edit);
DeleteButton.setVisibility(View.INVISIBLE);
EditButton.setVisibility(View.INVISIBLE);
//...
When the use scrolls the list all the views will have the Buttons visibility set to GONE and the onItemCLick() logic will work only for visible views.
I dont know if i understand your question correct but make the definitions of the ImageViews
ImageView DeleteButton = (ImageView) v.findViewById(R.id.button_delete);
ImageView EditButton = (ImageView) v.findViewById(R.id.button_edit);
one time at onCreate() and not every time again! Dont know if this solves your problem but try it.
Edit:
if(tempEditButton != null && tempDeleteButton != null){
tempDeleteButton.setVisibility(View.INVISIBLE);
tempEditButton.setVisibility(View.INVISIBLE);
}
EditButton.setVisibility(View.VISIBLE);
DeleteButton.setVisibility(View.VISIBLE);
tempEditButton = EditButton;
tempDeleteButton = DeleteButton;
This is an old question but I think I can still answer it. I solved this problem by creating a public static method which can be called from anywhere:
public static void hideOptions(Activity activity){
for (int i = 0; i< listviewSize; i++) {
Listview x = (Listview ) activity.findViewById(R.id.contactRecyclerView);
x.getChildAt(i).findViewById(R.id.myView).setVisibility(View.GONE);
}
}
You can then call this method whenever you want to hide your view

Categories

Resources