This comes more out of curiosity. I have had this snippet:
View mView = mInflater.inflate(R.layout.myButton, null);
ImageButton button = (ImageButton) mView.findViewById(R.id.mButton);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
...
And first I tried it without the mView-reference and it works as expected. So it is also described in the Buttons-section of developer.android.com
However, with mView also works.
My question is, is it really needed to reference it? And what could be the purpose behind it?
Why it works both ways? Could there be any drawbacks of any of the given usages?
Thanks.
Why it works both ways?
if it works both ways it could mean two different things. First you passed myButton.xml to setContentView as well. In this case the Activity has, as part of its view hierarchy, a view with id mButton. It works as expected, but of course, the OnClickListener, in the case of the inflated layout is purpose less, unless you add the inflated view to the Activity's view hierarchy. If you didn't pass myButton.xml to setContentView, it means that you have two separate layouts that contain the same ImageButton with the same id. Also in this case are valid the considerations about OnClickListener.
You are in two case:
Case 1
(Button) findViewById(R.id.mButton);
You are in an activity, where Activity.findViewById() will browse the actual activity view tree.
This activity will have a view from the moment you use setContentView(), addContentView(..) or other inflater method
Case 2
(Button) mView.findViewById(R.id.mButton);
You are searching for a view in another view, using the View.findViewById(). This method is used for getting a view from a Fragment for example.
Related
I've been looking around stack for 3 days now, and still haven't been able to solve this problem. I might not be looking in the proper areas, so please let me know if this question already has a semi-direct answer to it somewhere.
Basically, I have a tabbed activity where I created fragments for each tab, and I realize now, after searching through questions and answers for 3 days, that there's like a different syntax to link a button to the java file.
I'm trying to get this button to simply dissappear after it's click but I keep getting the error saying that it's accessed from within an inner class and needs to be final?
Please help me out with this, fairly new to coding (rep is exactly 1) trying not to bring that down right now.
Any help is appreciated!
You can use v.setVisibility(View.GONE).
You don't necessarily need the button reference
Try declaring your button like this:
final Button buttonOS = (Button) rootView.findViewById(R.id.buttonOS);
Also, you should move your logic from onCreateView() to onStart(). Your button hasn't been created yet, so you'll likely get null errors with getView()
By the way, if you click to bring your cursor to the error, you can press Alt+Enter to bring up the autocorrect menu.
Try doing this in onViewCreated instead of onCreateView:
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.buttonOS).setOnClickListener(...);
}
Try this ...first declare the variables Globally
View view;
Button button;
In your onCreateView
button = (Button ) view.findViewById(R.id.button_id);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//do something here (click function)
}
});
Hello i have just started learning android application development and i am watching a lot of tutorials but none of them really describe step by step so my question is :
i have created a simple app which contains on TextView one EditText and one Button
i have added android:onClick="onButtonClick" to my Button so it will trigger the onButtonClick method , now , i would like it to print out the userinput from EditText so what i did is :
public void onButtonClick(View v){
Toast.makeText(v.getContext(), email.getText().toString(), Toast.LENGTH_SHORT).show();
}
but why the method has to contain the View v ? where is it passed from ? and what does it contain ? it contains the button which i clicked ? and what does the v.getContext() do? why my app does the same when replacing the v.getContext() with this ?
That are many questions at once, but I try to answer them one by one.
but why the method has to contain the View v ? where is it passed from ? and what does it contain ?
Consider the documentation of View.OnClickListener:
View: The view that was clicked.
So you are correct in your assumption that it is the View that has been clicked.
and what does the v.getContext() do?
The first parameter of the Toast#makeText method is a Context. Basically the Context is a container of global information in an Android application. The Toast needs it to retrieve information to show itself.
why my app does the same when replacing the v.getContext() with this ?
I assume your method resides in an Activity. An Activity is a subclass of Context and can be used as a parameter.
If you click a button then View is passed. ViewGroup is a group of View example LinearLayout, Relative Layout, FrameLayout,etc. View is a part of ViewGroup. According to Official Documentation, A View occupies a rectangular area on the screen and is responsible for drawing and event handling. View is the base class for widgets, which are used to create interactive UI components (buttons, text fields, etc.). The ViewGroup subclass is the base class for layouts, which are invisible containers that hold other Views (or other ViewGroups) and define their layout properties.
I hope you understand well about what is View and ViewGroup!!
In one of my Fragments I have a method I call from the parent Activity. The method is nothing special, it simply scrolls my ListView to a position.
public void scrollToSomething() {
mListView.smoothScrollToPosition(The position I supply);
}
When I call this method initially, it works just like I expect, but when I rotate my device and call it again, I throw a NullPointerException from my ListView. I'm very much lost as to why this is happening. I've tried calling setRetainInstance(true). I've tried checking to see if my ListView is null before I call the method and if it is, then I initialize it again, but this does not work either. I've tried changing my onCreateView in a few different ways, thinking maybe something is going wrong there.
onCreateView
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
/* The View for the fragment's UI */
final ViewGroup mRootView = (ViewGroup)inflater.inflate(R.layout.fragment_list_base,
container, false);
/* Initialize our ListView */
mListView = (ListView)mRootView.findViewById(R.id.fragment_list_base);
return mRootView;
}
The Fragment is attached to a ViewPager using a simple FragmentStatePagerAdapter. I've tried carefully looking through the onDestroy methods of my Fragment and the parent Activity to see if I'm calling something that may cause the error, but nothing stands out. I'm not sure if what I'm experiencing is some sort of bug, or if I'm just overlooking something. Any help or advice would be huge. I'm not entirely sure what else to add because I'm just pretty lost as why this is happening, but if anyone has a question, I'll post any code you may see fit.
This may help you
If your android:targetSdkVersion="12" or less:
android:configChanges="orientation|keyboardHidden">
If your android:targetSdkVersion="13" or more:
android:configChanges="orientation|keyboardHidden|screensize">
I run a setText command inside of a fragment activity to try and set the text of a textView in the parent activity, but it's not working. Any ideas?
TextView text = (TextView) getView().findViewById(R.id.status);
text.setText("Text from a fragment");
I don't get an error in eclipse, but I get a null pointer exception during runtime. Of course it happens at the line where I setText. Any ideas on how to do this?
Use getActivity(). It will cause the findViewById() method to start the search at the base activity and bubble up until it finds your "r.id.status".
TextView text = (TextView) getActivity().findViewById(R.id.status);
text.setText("Text from a fragment");
Yes your NPE will probably be because R.id.status is probably not defined in the fragment's view.
getView() will return the view that is generated in your Fragment's onCreateView() method.
Are you trying to set a TextView in your Activity from a (secondary) FragmentActivity or trying to set a TextView in your FragmentActivity from a Fragment?
If it's the 1st option, you'll want to do something like use a message handler and pass the 2nd Activity a message. I don't think this is what you're asking though.
If you're wanting to set a TextView from a Fragment, the general way to do that is to define an interface on your FragmentActivity with a method (updateText() for example) and get the Fragment to call the method. The Activity then handles the TextView update, which works nicely because it can call getView() which will return the view you're looking for. It's similar to my answer posted here
I've looked everywhere for a solution to this, but I can't figure out how to implement it. My OnItemClickListener was disabled somehow on my ListView rows, because I have an ImageButton in the row layout, which takes over the focus. There have been numerous questions I've found, but none of them have gotten me anywhere.
I've checked this question, but I couldn't really make heads or tails of it. I just need a way to get the rows clickable so that I can detect when a row is pressed. Long press and focus work fine.
Instead of an OnItemClickListener, add an OnClickListener to each of your views returned from your adapter. You'll need to use setItemsCanFocus setting up your list:
ListView list = (ListView) findViewById(R.id.myList);
list.setAdapter(new DoubleClickAdapter(this));
list.setItemsCanFocus(true);
and then in your Adapter's getView, this will yield a clickable row. The button is assumed to be in the inflated xml.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = View.inflate(context, R.layout.cell, null);
view.setClickable(true);
view.setFocusable(true);
view.setBackgroundResource(android.R.drawable.menuitem_background);
view.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
new AlertDialog.Builder(context).setTitle("touched").show();
}
});
return view;
}
set your ImageButton's attribute:
android:focusable="false"
Because AbsListView.onTouchEvent check child.hasFocusable().
I've tested the following solution on SDK levels 8 and 16.
In getView()
setFocusable(false);
setClickable(false);
rather than setting them true in the Adapter's getView() does what I think the original question wanted, and means that an OnItemClickListener gets called, provided that an OnClickListener is not set in getView().
I'm assuming that anything you can do in an View's OnClickListener you can do just as easily in a ListView's OnItemClickListener.
(setOnClickListener on a View implicitly sets the view to be clickable, which prevents the ListView's corresponding OnItemClickListener getting called, apparently.)
The behaviour is as one would expect, in terms of the ImageButton's visual state when the item is pressed or rolled over.
The solution is a slight illusion, in that it is the list item that's being pressed not the ImageButton itself, so if the button doesn't occupy whole list item, clicking somewhere else in the item will still make the button's drawable state reflect the click. Same for focus. That might be a price worth paying.
This will definitely work. Add this to the layout definition.
android:descendantFocusability="blocksDescendants"
Found the solution here
One alternative to setting an OnClickListener for every view is to NOT use an ImageButton - use an ImageView instead. The ImageView can still send events to an OnClickListener and won't take over the focus.
best way to do is this:
android:focusable="false"
android:focusableInTouchMode="false"
set these properties for that Imagebutton and try.
I
For my version of this problem, the issue was that I had set my TextView object to android:inputType="textMultiLine". When I removed this line the issue of the list not being clickable was gone. Looks like a nasty little bug.
Also, I'm still able to use the android:minLines/android:maxLines properties with no problem, so it's not a big issue. Just not the solution I expected.
The following line solved the issue in my project:
<TextView ... android:textIsSelectable="false" />
As an alternative solution which worked for me you can try to extend your adapter from BaseAdapter (iso implementing ListAdapter interface)
Put This code ImageView nextpage= (ImageView)findViewById(R.id.btnEdit); instead of ImageButton . now the list item is active
I have sub-classed ImageButton and setFocusable="false" in layout definition didn't work for me. It solved calling setFocusable(false) in constructor of subclass.
Using a ScrollView can prevent the onItemClickListener from receiving the input.
Hope this helps anyone.