android adapter data changed to notify host activity - android

This is a my use case. I have an activity with a listview and a textview. The textview is the sum of all numbers on the listview, the listview has all the numbers.I have a custom adapter for this case.
On each row of the listview, I have a button. This button will change the number on this row.
what I want to do is this:
when user clicks the button, the value on each row is changed - doable.
the sum on the textview also changes accordingly.
This is a simplified example. In reality, I also have a constraint that I have a data model to represent the data on each role. I am not able to extend the data model to DataSetObserver.
any help?

You should create a listener, which listens for touch on your increment button and inside it call a method of the class extending an interface you created.
To make it easy, in your adapter you will have:
public interface OnIncrementListener{
onNumberIncremented();
}
private OnIncrementListener mListener;
//This is inside getView method of your adapter
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mListener.onNumberIncremented();
}
});
Then your activity
public class MyActivity extends Activity implements OnIncrementListener {
//inside onCreate
myAdapter.setOnIncrementListener(this);
//end onCreate
#Override
public void onNumberIncremented() {
//Change value of your TextView here
}
}

Related

Handling onLongClick of a child view in the Main Activity

I have a Main Activity that has a bunch of child views and then I have a ListView whose items are dynamically generated. I'd like to be able to long click any of these items and have this event handled in the Main Activity.
MainActivity
LinearLayout
ListView
Item - (long click here)
Now I know how to subscribe the the onLongClick event of the dynamically created ListView item itself but that's in the adapter I use to create the items.
What I was hoping was, that I could simply subscribe to the onLongClick event of the Main Activity and I'd see the event from the dynamically created ListView item propagate up to the MainActivity. But that's not happening.
My MainActivity implements View.OnLongClickListener, like so
class MainActivity : Activity(), View.OnLongClickListener {
override fun onLongClick(v: View?): Boolean {
Log.d("APP", "LongClicked: ")
return true
}
......
}
However, I'm not sure how to set the handler in the Activity itself. That is, for onClick, I would set android:onClcik="onCLick", in the XML of the Main Activity, however, I don't see an option to do the same for onLongClick
Also, I have not set any attributes such as android::longClickable="true/false"
any of the views. I'm a bit confused by the true/false and what the actually mean.
Any help would be appreciated.
UPDATE
I tried calling the setOnLongCLickListener on the ListView in the Main Activity, since I have access to the ListView there. Like so
availableZonesListView = findViewById(R.id.availableZonesListView)
availableZonesListView!!.onLongClickListener(this)
The MainActivity ('this') implements the View.OnLongClickListener and I see events coming in there when I long click directly on the MainActivity/Layout. But I don't see eventing coming in there when I long click on the items of the ListView
Now I know how to subscribe the the onLongClick event of the dynamically created ListView item itself but that's in the adapter I use to create the items.
public MainActivity extends .. implements MyClickListener {
... onCreate {
... = new MyAdapter(yourParams, this); // `this` is the new param
}
#Override
public void onAnyItemLongClicked() {
// Do whatever you want
}
}
Create your new interface:
interface MyClickListener {
void onAnyItemLongClicked();
}
Then in your adapter where you "Now I know how to subscribe the the onLongClick event". It would be something like this:
public class MyAdapter {
// other fields
private final MyClickListener listener;
public MyAdapter(otherParams, MyClickListener listener) {
.. assign other params
this.listener = listener;
}
}
// However you set your item click listener (in getView)
adapter.setOnItemLongClickListener(new OnItemLongClickListener() {
#Override
public void onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
listener.onAnyItemLongClicked();
}
});
This will propagate the click event from the adapter to the activity.
(I had to improvise a bit because you didn't share many code details)

I have an activity with recycler view adapter class, when button clicked in adapter class I want to refresh the main activity

I have an activity with RecyclerView.Adapter class. RecyclerView contains button. When click that button I want to change a value defined in main activity and display it in TextView that also defined in main activity , otherwise I want to refresh the activity.
I already tried some code like:
Android, How to call onCreate() explicitly from other method?
How to restart the onCreate function
YourActivity extends Activity implements YourAdapter.ClickCallback{
#override
oncreate(Bundle bundle){
// initialize views
YourAdapter adapter = new YourAdapter(this);
// do something with your adapter
}
#Override
public void updateView(){
//update your views here
}
}
//In Recycler Adapter pass ClickCallBack As parameter
class YourAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ClickCallBack clickCallBack;
public YourAdapter(ClickCallBack clickCallBack){
this.clickCallBack=clickCallBack;
}
//ClickCallback Interface
interface ClickCallBack {
void updateView();
}
//In your ButtonClick
clickCallBack.updateView();
}
You can also add parameters in updateView method.
Pass an instance of those TextView through constructor and update the value there in the Adaptor. That would be the easiest way.
You don't need to recreate Activity in this case. The best solution would be:
Declare an interface.
Implement it in Activity(here implement your updates to TextView, etc.).
Pass object that implements the interface to your adapter.
Call the method on this interface in adapter.
Here is example:
https://stackoverflow.com/a/32720879/2528967

GetSelectedItem on OnItemClickListener (Android)

let's say you have a listview with custom xml-objects on it in a row.
But you want to address specifically the textview, if it's press in the OnItemClickListener. What's the way - or bette - the best practise to do so? If i check in the OnItemClick method, the specifically element in the row (e.g. the textview, doesn't get recognized.
You can add onClickListener to that textView in the getView method of your adapter like this.
viewHolder.myTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG,"item= "+data.get(position).getTitle());
}
});
For this to work create a class which extends BaseAdapter class and implements all its method
1.Now in the getView() method of this class initialize all the required views in a single item of listview
2.After that attach onClickListener() to the desired textView.
3.After that select your custom adapter class in the listView.setAdapter() method
This should help you if it doesn't work use RecyclerView instead and do all the above task in the onCreateViewHolder() method of RecyclerView.adapter Class
if you have model class name **User** now you can get user info by using
viewHolder.tv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
User user = data.get(pos);
user.getTitle();
Log.d(TAG,"item= "+data.get(position).getTitle());
}
});

Is there a way to hide specific listview items from the main activity?

Just wondering if what I'm trying to do is possible. So i have a custom adapter for a listview. It contains a textview and two buttons. I would like one of the listview buttons to remain hidden unless a specific button is pressed on the main activity.
So far I have the listview buttons performing their intended function but I have no idea how I would even begin to get what I'm wanting.
Sorry, for clarification, I have one button completely separate from the listview that is just always there. When I press this button I would like to toggle the visibility of a button that is on each listview item all together. The best example of this that I can think of is having a list of items and a button that can toggle off the 1. 2. 3. 4. that comes in front of each item.
Create a method in your adapter for knowing you have clicked the button from your main activity like this
public void buttonIsClicked(){ //in your adapter
buttonhide.setVisibility(visibility?View.VISIBLE:View.GONE);
}
And call this method from your activity on btnclick.
like
yourAdapter.buttonIsClicked();
and call this method for notifying the adapter about the change.
yourAdapter.notifyDatasetChanged().
or
You can use an interface for listening to the clicks in main activity and implement that listener in your adapter
Set visibility gone to the button you want to hide by calling code
buttonhide.setVisibilty(VIEW.GONE);
hide it in oncreate() of your activity and make it shown on the button click event by calling code buttonhide.setVisibilty(VIEW.VISIBLE);
Below is the code
btnView.setVisibility(View.GONE);
yes it is possible to do that.
First have a Model class to back the listview data and keep a flag in that model which indicates whether to show the button in that row's data model. On certain condition change that model's flag and call notifyDataSetChanged() on adapter.
Ex:
class Model{
String label;
boolean showBtn;
}
in adapter's getView()
Model model = list.get(position)
if(model.showBtn){
btn.setVisibility(View.VISIBLE);
}else{
btn.setVisibility(View.GONE);
}
in Activity
disableButton(){
modelList.get(0).setShowBtn(false);
adapter.notifyDataSetChanged();
}
This code will hide button in first row
Add a Boolean value in your dataset which represent the Visibility state of the button.
public class Dataset {
private boolean visible;
public boolean isVisible() {
return this.visible;
}
public void setVisible(boolean visible) {
this.visible = visible;
}
//..more items
}
Then in your getView method of the Adapter check this Boolean value to show/hide the button.
boolean visibility = yourDataset.get(position).isVisible();
yourButton.setVisibility(visibility?View.VISIBLE:View.GONE);
And when the Button outside of your listview is clicked Update your dataset. And call yourAdapter.notifyDatasetChanged().
What you are attempting is: manipulating the visibility of the button declared in the Adapter from the containing activity. Simple, put a controlling variable in the activity and pass it a parameter to adapter.
Boolean mShowButton; //a controlling variable
void onCreate(Bundle savedInstanceState) {
...
mAdapter=new MyAdapter(...,mShowButton);
mButton.setOnClickListener(actionShow );
}
OnClickListener actionShow = new OnClickListener() {
#Override
public void onClick(View button) {
mShowButton=true;
mAdapter.notifyDataSetChanged();
mListView.invalidateViews();
}
};
And do this in your adapter,
Boolean showButton;
public MyAdapter(Context context, List<String> myList, Boolean showButton) {
...
this.showButton=showButton;
}
public View getView(int position, View rowView, ViewGroup parent) {
...
if(showButton){
mButtonTwo.setVisibility(View.GONE);
}else{
mButtonTwo.setVisibility(View.VISIBLE);
}
}

Android: Inform main activity about CheckBox of custom ListView

I have a Custom BaseAdapter showing a ListView containing a TextView and a CheckBox. The TextView has an OnClickListener implemented to perform a specific action when clicked on the text. Within the Adapter I have a OnCheckedChangeListener registered which keeps track of which item is checked (because of the ListView recycling).
I want to start an ActionMode when I check a CheckBox and stop it when I uncheck it.
How can I inform the main activity hosting the adapter that a check has been made?
Create a listener call back interface, something like:
public interface ListenerCheckBox
{
public void onRowChecked(int rowNun);
}
Then, make your main activity implement this listener:
public class ActivityMain implements ListenerCheckBox
Then, when you instantiate your custom BaseAdapter, pass in the listener:
//kv 3rd parameter would be listener
CustomBaseAdapter customBaseAdapter = new CustomBaseAdapter(this, items, this);
Then, in the constructor of your CustomBaseAdapter, set a member field to the listener:
public CustomBaseAdapter(Context context, ArrayList<Item> items, ListenerCheckBox listenerCheckBox)
{
mListenerCheckBox = listenerCheckBox;
...
}
Then, every time an item is checked, call:
mListenerCheckBox.onRowChecked(rowNum);
Here is a Android Studio project that shows an example of how to do what you are asking. In particular, check out the check listener and its onClick():
#Override
public void onClick(View v) {
if (mMode != null) {
mMode = mListView.startActionMode(new ExampleMultiChoiceModeListener(mActivity));
}
mListView.setItemChecked(mPosition, ((Checkable) v).isChecked());
}

Categories

Resources