Difficulty ticking checkbox inside BaseAdapter - android

I have a ListView with each row consisting of a TextView and a CheckBox.
The user is allowed to click on each TextView, and once he does a Dialog is presented to him where he is expected to either choose Yes or No.
When he chooses Yes, another activity is presented to him where he needs to enter data.
I am implementing all this inside a base adapter class, so inside the base adapter I created the AlertDialog and handled it's OnClickListeners.
Here is the problem: I need to use startActivityForResult in order to get back the data that the user will enter in the new activity, and like I said above, I have done so in the BaseAdapter. Now, how can I get the data from the new activity back inside the BaseAdapter? I researched various sources and found out that one cannot start an Intent directly from a BaseAdapter class, but instead needs to reference the Intent to the calling activity like below:
((Activity) mContext).startActivityForResult(intent, 1);
This would then result in having the the onActivityResult() method in the adapter Activity and not inside the BaseAdapter.
I need to leave the code inside the BaseAdapter for various reasons.
The value I need to retrieve is a simple boolean that if it results to true, will tick the CheckBox next to the selected TextView.
How could I implement this? What alternatives do you guys suggest? I tried creating a method inside the BaseAdapter so that I can call it from the "main" Activity at the OnActivityResult() but the CheckBox that I need to tick is returning null at that point; the reason being quite obvious.
I would appreciate any help on this matter.
Inside BaseAdapter class
final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle("Materials");
builder.setMessage("Did you require any materials to fix this error?");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
String clickedError;
clickedError = holder.text.getText().toString();
Intent intent = new Intent(mContext, Material.class);
intent.putStringArrayListExtra("materialList", materialList);
intent.putExtra("clickedError", clickedError);
intent.putExtra("repairID", repairID);
((Activity) mContext).startActivityForResult(intent, 1);
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
if(checkbox.getTag() == v.getTag())
{
checkbox.setChecked(true);
}
}
});
builder.show();
// Method to tick the checkbox.
public void TickBox(CheckBox cb)
{
cb.setChecked(true);
}
The main activity containing OnActivityResult()
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if(resultCode == RESULT_OK)
{
boolean moreThanOne = data.getBooleanExtra("moreThanOne", false);
if(moreThanOne)
{
CheckBox cb = adapter.checkbox;
adapter.TickBox(cb);
}
else
{
// ....
}
}
}

Create a Callback listener inside your BaseAdaper, inside that method write Intent code,
For updating it later Create a method inside the BaseAdapter which will gets called from onActivityResult.

u can update ur checkbox from ur activity.... TRY this
when user click the listview send the listItem position to ur new activity.AND return the same value in ur old activity in onActivityResult.
then in onActivityResult **
use the same layout that u r using when creating listView
RelativeLayout itemLayout = (RelativeLayout)mListViewObject.getChildAt(i);
CheckBox cb = (CheckBox)itemLayout.findViewById(R.id.checkBox);
cb.setChecked(RESULT);

Related

How can I let a fragment know that the ArrayList was updated

So I have an ArrayList of a custom object and an adapter to show the contents through a ListView. You can click on separate objects in the ListView and a little animation expands and shows some extra informations. This behaviour is defined in the ArrayAdapter (because the animations didn't work how I wanted it to when used directly in createView().
Now if you click on a small image (X- to delete) of a listview element, an alertdialog pops up asking you if you're sure you want to delete that item. If you click Yes it removes it from the arraylist but notifyDataSetChanged(); doesn't refresh the adapter and onResume or something similar is never called because I never hid the fragment, just had an alert over it.
this is a rough code, part of my ArrayAdapter:
deleteIcon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
...
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
ArrayList<Book> XYZ = sharedFunctions.loadSortedArrayList(getContext());
XYZ.remove(position);
sharedFunctions.saveArrayList(context, XYZ);
notifyDataSetChanged();
break;
case DialogInterface.BUTTON_NEGATIVE:
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage("BLABLA").setNegativeButton("Cancel", dialogClickListener).setPositiveButton("Confirm", dialogClickListener).show();
}
});
So how can I tell the Fragment (which is a tab) that the data has changed?
EDIT:
So I think the answers below were technically correct but I figured out that I was simply doing this all wrong. I removed the item from the ArrayList (which was loaded/saved in SharedPreferences) instead of removing it from the ArrayList that was used to construct the adapter. Stupid mistake tbh. Once I removed it from there as well, notifyDataSetChanged() worked. Thanks to you both for trying to help.-- (pretty new here so I'm not sure if i should delete the question but I'll just keep it like this for now).
You have to access your fragment through the fragment manager. Here is an example how to do so:
ExampleFragment fragment = (ExampleFragment) getChildFragmentManager().findFragmentByTag("theTagThatFragmentSavedInFragmentManagerWith");
if (fragment != null) fragment.notifyItemChanged(itemPosition);
For this you can also use localbroadcastreciever too. define and register local braodcast in that fragment which you want to refresh and call that broadcast from adapter delete positive click. in broadcast onRecieve just check your adapter is not null and do like this
youradapterobject.notifyDataSetChanged();

Update recyclerview adapter onResume from Different Activity

So I have a fragment with recyclerview in it which is a direct child of my first Activity. In my recyclerview rows I have imagebutton. So for my second activity I have a feature where it can change the image of the imagebutton from my first activity's recyclerview. Can somebody help me?
Update:
My application has an addtocard feature. So in the first activity there's individual imagebutton for every row of my recyclerview. When i tap the imagebutton, the image will change and it will be added to the cart. I also have a database for the cart so the ID's of the product get inserted when it is added. If i tap the recyclerview row it will call the second activity and will display the product. So in the second Activity I also have the add to card feature. The problem is when I add the product in the cart inside the second activity i want to update the recyclerview in my first activity to indicate that it was already added.
You need some kind of shared state where the fragment can read from and the second activity can write into. Since I don't known what you use case is I would suggest that you use SharedPreferences for the first POC implementation.
In the onBindView of the adapter of the fragment you check the preferences for the image to use. It can be a R.whatever.id or a URI pointing to the image. In the second activity you set the key to the image resource depending on your requirements.
Or, this might be a better solution actually, pass the reference to the image in your data source of the adapter. Then whenever you need to update the image write the value in the data source and notify the adapter that there are some changes. If you don't use a content provider and are not observing the data source, then reload the contents in the onResume method of the fragment.
But to provide a more accurate answer we need more informations about your use case and the existing code.
Use Callback or Interface. Tigger it when you click and use that interface method to set the Change the Image. Actually I don't Understand Your Question properly. Can you please provide the Code. So i can give proper Answer. What i understand i gave the Answer.
You should pass your model object and list position to second activity.
FirstActivity.java
private static final int REQUIEST_ITEM_DETAILS = 150;
private void showItemDetails(Item item, int position) {
Intent intent = new Intent(context, SecondActivity.class);
intent.putExtra(SecondActivity.EXTRA_ITEM, item);
intent.putExtra(SecondActivity.EXTRA_POSITION, position);
context.startActivityForResult(intent, REQUIEST_ITEM_DETAILS);
}
SecondActivity.java
private Item item;
private int position;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
item = getIntent.getParcelableExtra(EXTRA_ITEM);
position = getIntent.getIntExtra(EXTRA_POSITION, -1);
}
/*
* finish your activity with onBackPressed function. so android device's
* Back button and your finishing operation will be same function.
*/
#Override
public void onBackPressed() {
Intent intent = new Intent();
intent.putExtra(EXTRA_ITEM, item);
intent.putExtra(EXTRA_POSITION, position);
setResult(RESULT_OK, intent);
super.onBackPressed();
}
and in your FirstActivity.java catch onActivityResult
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_ITEM_DETAILS) {
if (resultCode == RESULT_OK) {
int position = data.getIntExtra(SecondActivity.EXTRA_POSITION, -1);
Item item = data.getParcelableExtra(SecondActivity.EXTRA_ITEM);
/* put setItem function to your adapter class. it will just replace given item with in your list item */
adapter.setItem(position, item);
adapter.notifyItemChanged(position);
}
}
}

Retrieving item from AlertDialog to Activity from a ListView

I'm working on an android app and my requirement is that, I need to display the cursor values into alertdialog and let the user choose an item from the list and the value selected should be returned to the calling Activity.In my app, based on the student info, the cursor holds the values of courses he is taking. So the user should be able to choose one of the courses and then that value should be returned to the Activity that called alertdialog. Can you please let me know how to proceed on this.I've looked at multiple examples and none seems to work exactly.
Here is my sample code
final AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());
final Cursor courses=dbConnector.getCourses(student);
builder.setTitle("Enter Course");
builder.setCursor(courses, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int itemSelected) {
if (courses.moveToPosition(itemSelected)) {
String text=courses.getString(0);
Toast.makeText(getApplicationContext(),
"You selected: "+text,
Toast.LENGTH_SHORT);
builder.show();
}
courses.moveToFirst();
}
},"course");
builder.create();
createRow(sview, student, pass,text);
Now I want to return the text variable to the Calling Activity but, here it is local to the onClick() method. How can we do that without having to extend any DialogFragment class.
I suggest you calling a method of the class inside overridden onClick method and do whatever you like with that because the method will be in the Activity like here
#Override
public void onClick(DialogInterface dialogInterface, int itemSelected) {
myMethod(itemSelected);
}
private void myMethod(int selectedItem){
//Do whatever with that selected item
}

how to make my checkbox unchecked

I've got big problem with checkbox. I've got chceckbox in my MainAdapter(not Activity), I'm checking it and go to the next actvity by clicking on button. Then I return from DefaultActivity to MainActivity and I want checkbox to be unchecked. I also add that checkbox's logic is in Adapter in ViewHolder like this :
class ViewHolder {
TextView tv1;
TextView tvC;
ImageView ivT;
CheckBox chb;
}
and all logic is in getView method.If you don't understand something and you want me to help. Just ask what you want to get.
When you start your new Activity, do it calling startActivityForResult(). This will call a callback method once you close your second activity, so this way you make sure you'll enter that method once you finish() your newly opened Activity.
Once in there, simply find your view by id, and uncheck it. This is a sample code:
final Intent intent = new Intent(YourActivityThatContainsListViewDefinition.class, YourNewActivity.class);
startActivityForResult(intent, 1);
Afterwards, just override the onActivityResult() method.
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
switch (requestCode) {
case 1:
CheckBox cb = (CheckBox) findViewById(R.id.your_checkbox_id);
cb.setChecked(false);
break;
}
}
---- EDIT ----
All this code would be outside your Adapter implementation - so, if you look at the code I provided, in the Intent, the first parameter is the context of the Activity that opens the second one. That means that those two overrides, you have to implement them in the Activity that calls the other (in your case, the MainActivity).
In your second Activity (DefaultActivity), you need to do nothing, just notify the first Activity (MainActivity) that it has to unckeck the CheckBox. To do so, you simply do something like this when you want to close DefaultActivity:
Intent returnIntent = new Intent();
setResult(RESULT_OK, returnIntent);
finish();
This way, you're notifying MainActivity that it should fire onActivityResult() and there's where you uncheck that CheckBox.
To uncheck your checkbox do:
chb.setChecked(false);
if is in adapter you can retrieve it in when getView() is called...
e.g.
holder.chb.setChecked(false);
with this the checkbox will be unchecked every time that de adapter is notified or created again

onListItemClickListener: passing the long id value

UPDATE
The original question i asked was about my long id value but because you guys were right in the way u said i had the correct id i removed my error. Thanks for the help. read my answer for more detail.
1) My app uses the local android SQLiteDatabase and has three tables. I have no problems for two of the tables but turns out my third one is presenting some issues because of my column declarations are public static final string COLUMN_NAME = "name"; ,etc.
My Activities are not extending the ListActivity so that I can have custom lists and listviews for each activity.
I am getting my listview by listview = (ListView) findViewById(R.id.myList); and adding a listener to the listview by listview.setOnItemClickListener(ListListener); Then here is my method for the list listener:
OnItemClickListener ListListener = new OnItemClickListener(){
public void onItemClick(AdapterView<?> arg0, View v, int position,
final long id)
{
AlertDialog.Builder dialog = new AlertDialog.Builder(ExerciseList.this)
.setIcon(R.drawable.edit)
.setTitle("Update Selected Exercise")
.setMessage("Would you like to update the current Exercise? Click continue to proceed.")
.setPositiveButton("Continue", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
final Intent i = new Intent(getBaseContext(), AddExercise.class);
i.putExtra(ExerciseDbAdapter.KEY_ROW_ID, id);
startActivityForResult(i, EDIT_EXERCISE);
}
})
.setNegativeButton("Back", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
dialog.show();
}
};
This above method is just a working on list item click listener!
Intent.putExtra("Key",value) is right way to put the data in intent so
i.putExtra("INSERT THE KEY HERE",ExerciseDbAdapter.KEY_ROW_ID, id);
Okay guys so i found the issue with my application and you were all right. I was getting the correct row id from the application.
I however was passing another data member through my intent causing the setRowIdFromIntent() method to change the id from null to 0. or from not null to 0.
Basically no matter what the value i was passing it was being set to 0 from my setRowIdFromIntent() method because of the data member i passed through. Therefore the above code is almost irrelevant to my problem.
So if you want a working on click list listener the one above will definitely help you pass the correct id to your new activity. Sorry again for this confusion I had on my side. Thanks again for all other postings!

Categories

Resources