getViewById() in ListView NullPointerException - android

I have a View in a custom layout of a ListView, now I want to assign an onClickListener to this View (in a Fragment). But if I try
getActivity().findViewById(R.id.rowleft).setOnClickListener( ...
it throws a NullPointerException. Why is this? In the layout file the View has the ID "rowleft" Does the id change when it is in a ListView? Or how do I see which row triggered the event?
What I want is two Views in one Item to know if the user clicked on the left or the right side.
Thank you

Set up your OnClickListeners in your adapter getView() where you're setting up the listview item view anyway.
You can override getView() in an ArrayAdapter. Call super.getView() to get the view to call findViewById() on for the purpose of setting click listeners.
Don't call findViewById() on the activity. Even when the listview items are part of the activity hierarchy, it's not really practical to find views with the same id from different listview items.

ListView.getChildAt(x).findViewById(R.id.rowleft).setOnClickListener( ...

Related

Difference between setting onClickListener in adapter and in fragment

In my code I have fragment and gridview in it. Also I have ArrayAdapter for this Gridview. Now I need to change background color of grid cell on click. I do this by setting onClickListener.
Question is what is difference between setting onClickLister for GridView cell in adapter and in fragment?
I'm gonna try to clarify the different android entities involved in your question a little.
A GridView is a View.
You can assign Click Listeners to Views so they react to a user click. Any view has a generic clicklistener (View.setOnClickListener) that gets called whenever the user clicks on any part of the view
Complex views can have several other more specialized clicklisteners, for example, menu-like views (ListViews, GridViews, etc) will have also a setOnItemClickListener / setOnItemLongClickListener that gets called whenever the user clicks on an item (vs. the whole view)
An Adapter is just a class whose purpose is to build views with data to data-consuming views. For example, your GridViewAdapter: It will get called once for every row and it will construct each Row View (in the getView method). Every Row View will be (probably) a ViewGroup (FrameLayout/RelativeLayout...) with some other views inside (ie. Icon ImageView, name TextView, address...)
So the adapter itself doesn't accept clicklisteners. But the Views created by the adapter can! For example, let's assume your GridView is a Phone List:
Your GridView has an ItemClickListener to react to the selected phone list entry and show info about the contact
Your GridView adapter builds views for every row. Imagine your 'contact' rows have 3 views: A title, an Icon, and a button to delete the contact
Inside your adapter, you will assign an onClickListener to the "delete contact" button View. Mind you always assign onClickListeners to Views, not to the adapter itself ("you can't click an adapter!")
About Fragments, think of them as "sub-activities". A fragment contains a root layout with several views. Again, it will be in those views where you assign the clicklisteners, not to the fragment itself.

On View click inside a RecyclerView row change the state of other rows inside the same RecyclerView

I have an ImageViewinside every row of my RecyclerView. I set an setOnClickListener inside method onBindViewHolder() of my Adapter so each time this ImageViewis clicked something happens.
But the problem is that I need to change the state of other rows inside the same RecyclerView. But they are not the current row at method onBindViewHolder().
Is there any way to from method onBindViewHolder()change the state of ImageViewin another row that is not the current one, if I know the position/index of the other row I want to change?
What you can try is for example creating a CustomView for example MyRelativeLayoutas a wrapper of the item in RecyvlerView, that extends the view you need to change, once the user clicks the view this MyRelativeLayoutyou can have a method for example isClicked(boolean) so you put it isclicked(true) and then myAdapter.notifiyDataSetChanged().And then you can decide what to do to you imageView, for example if MyRelativeLayout isClicked() == true then change its drawable to whatever yo need or something like that.
hope this helps!

onClick listener for dynamic view in Listview inside Fragment

I have the following button-in-Fragment problem:
My custom adapter throws out a row in my listview. That row has a (remove) button.
When the user clicks on the button in the row, the row is removed (and he button as well, duh). I have this working perfectly in an activity. But, how does this work in a Fragment?
If I use findViewbyId in onCreateView it crashes, because the view simply does not exist yet.
onClick in xml is also not an option, that does not work for fragments.
Somewhere I should be able to place a onClick listener and be able to remove it with adapter.remove. But where to place it and what does it look like?
If I understand what you're saying correctly you should add the onCLickListener to the button from within your adapter.
Use onViewCreated() ..it is called after onCreateView, when the view returned has been added.

ListView and propagating click events from children views in the items

I have a ListView with custom items - 3 ImageViews and a TextView. I have a call to setItemsCanFocus(true), so I can make the ImageViews clickable. I'm currently using SimpleAdapter to populate the View.
I'd like to trigger the AdapterView's onItemClick event when one of those subviews is clicked. The onItemClickListener receives a view as the second argument and that can be used to identify which subview was clicked. Frankly, I was expecting this to be the default behaviour but it isn't, unfortunately.
Is there any way to implement this behaviour without bluntly breaking encapsulation (i.e. creating an Adapter that holds a reference to its View)?
What is the accepted way of dealing with events from views in list items? How do you keep the Adapter from knowing too much about the ListView?
Unfortunately you have to choose between using onItemClick() or onClick() on individual children. One way to do it however is to make the top-level view of each item clickable.
Setting android:addStatesFromChildren="true" on the listview in your xml will send clicks on the child elements to the onItemClick method in the onItemClickListener connected to your listview.

Refresh a ListView if I change the content of the ListItem

I have a ListView in my android activity. And I populate the ListView by sub-class the BaseAdaptor (which returns a View in getView() method).
What if in my click listener of a button in a list item view, I
change the text of the TextView in the List item view
or
change the dimension of the list item view by adding/removing children of the list item view
What is an efficient to refresh my listView? I don't want the listView to re-trigger a query since there is no data change.
Thank you.
if you just change the content of your Children View, you have not more to do than TextView.setText(newText).
If you change the count of your ListView childrens, you have to call BaseAdaptor.notifyDataSetChanged()
I was about to suggest that you invalidate(), but you don't want to trigger a redraw, so I can only suggest that some form of global flag is your best bet. Set the flag, invalidate or redraw and query (and reset) the flag in OnDraw()

Categories

Resources