I've got a custom LinearLayout with a smaller TextView child. I'd like to be able to click the area not covered by the TextView, so I set clickable=true and an onclicklistener to the LinearLayout, but onClick is not triggered. If I set the onclick listener on the TextView it works as expected...
Anybody can help?
ar_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ar_item" android:layout_width="202dp"
android:layout_height="62dp" android:background="#drawable/bg_item_ar"
android:clickable="true">
<TextView android:id="#+id/ar_item_txt"
android:layout_width="164dp" android:layout_height="fill_parent"
android:paddingBottom="8dp" android:paddingLeft="8dp"
android:paddingTop="8dp" android:paddingRight="6dp" android:gravity="center"
android:background="#50000000" />
</LinearLayout>
My custom LinearLayout
public class ARView extends LinearLayout
{
public ARView(final Context context, String name, String id)
{
super(context);
getLayoutInflater().inflate(R.layout.ar_item, this ,true);
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.ar_item, null);
TextView textView = (TextView) findViewById(R.id.ar_item_txt);
textView.setText(name);
setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Toast t = Toast.makeText(context, "hey!", Toast.LENGTH_SHORT);
t.show();
}
});
}
}
android:duplicateParentState="true" did not help me.
To make your layout clickable with its children you need add this option for every child:
android:clickable="false"
Then click handling will go up to parent.
for every child
android:duplicateParentState="true"
This isn't your case, but I had similar problem with clickable ViewGroup. After a hour of looking for solution a found out that I set android:inputType to TextView inside my ViewGroup which was blocking onClick() listener (no idea why)
Don't use android:inputType with TextView
Make Your parent LinearLayout's android:clickable="true"
Make all of the the childview's android:clickable="false"
Under Linearlayout - Remove android:inputType="" from TextView
The android:duplicateParentState="true" made my TextView looks like it's disabled, and cannot receive click event.
All you need is set the TextView clickable="false". So the click event will dispatch to parent layout, and the TextView still can react to touch event (with ripple effect).
Your TextView height covers the whole parent (whole layout) so you might clicking on empty space but not on the layout. Try using wrap_content for android:layout_height for your TextView. Set click listener for the layout as well.
You aren't using your custom View; you're using a standard LinearLayout. Your XML tag should be:
<com.yourcode.ARView ...> ... </com.yourcode.ARView>
One thing to make sure of is that another view is not on top of the view you are trying to click. This is especially common in FrameLayouts (where your sub LinearLayout may be covered) or with Relative Layouts you might have forgot to update this line:
android:layout_below="#id/shouldBeTheIdOfTheViewCurrentlyBeingCovered"
so that views don't fill the same space.
If the views in question are TextViews, you may need to set them as focusable="false" so that the first click isn't used focusing on the text view.
The problem may be from the textview that has android:layout_height="fill_parent" in its layout. If that doesn't fix the issue, the problem may be the onClick() event. The linear layout may not actually ever call onClick() since its a layout. Try overriding the onTouch() event listener instead.
Add the following attributes to the linearlayout
Any Click events not handled by the child views will be automatically passed over to the LinearLayout.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
android:focusable="true"
android:clickable="true">
<child/>
<child/>
</LinearLayout>
I faced the same problem, and all the XML Attributes didn't work. I am not sure if this happens because i programmatically inflate and add the views, but this is how i worked around the problem.
I have a Class which extends LinearLayout, with a TextView and an ImageView.
After inflating the layout and getting the views, I assigned the child views a OnClickListener, when pressed, executes the LineaLayout's onClickListner.
public class MyView extends LinearLayout {
private OnClickListener clickListener;
ImageView imageView;
TextView textView;
#Override
public void setOnClickListener(#Nullable OnClickListener l) {
super.setOnClickListener(l);
clickListener = l;
}
void afterViews() {
imageView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
clickListener.onClick(MyView.this);
return false;
}
});
textView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
clickListener.onClick(MyView.this);
return false;
}
});
}
I also tried overriding OnTouchListener, but then my child views didn't have the ripple effect, which I needed.
None of the solutions above forked for me. Than i noticed that a LinkMovementMethod set to TextView inside my LinearLayout. This class intercepts touch events, click events and properties of TextView such as clickable, focusable vs..
I faced the same problem, and all the XML attributes didn't work. I think this happens because I programmatically inflate and add the views. The fix for me was to - also that programatically - set the inflated root view not clickable:
View view = layoutInflater.inflate(R.layout.some_layout, someLinearLayout, false);
view.setClickable(false);
(Yes, I tried to have the some_layout not clickable in XML.)
android:duplicateParentState="true" >= not worked
focusable="false" >= not worked
clickable="false>= not worked
So i did a quick fix by adding Transparent Button on top with match_parent for height and width
Problem solved without any extra code,
Related
I have two rows of imageViews in a ScrollView. The imageViews all have onClickListener and when i want to scroll in this area it doesn't work. So i guess the Click listeners intercept the scrolling of the ScrollView. What's the best way to change this behaviour ?
My View hierarchy is like this:
<ScrollView>
<RelativeLayout>
<FrameLayout>
</FrameLayout>
<RelativeLayout>
</ScrollView>
in the FrameLayout i put a Fragment which has a LinearLayout in which i inflate other LinearLayouts like this:
productHolder.productLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
}
});
Maybe you could use an OnTouchListener instead of an OnClickListener.
In the OnTouchListener you can check if the action of the motion event was a click and consume the event (return true). Otherwise you can leave the event for other listeners (return false) to consume.
Note, that you might need to add some additional implementation for figuring out which image view was clicked, however without seeing your layout, it's hard to give you a hint how to do it.
I have a RelativeLayout positioned over the rest of my view and I want this RelativeLayout to stop anything underneath it from being clicked. Here is my document outline:
FrameLayout
LinearLayout
RelativeLayout
The RelativeLayout only has a background colour, and has nothing inside it. The LinearLayout has buttons and textboxes in it. I want to stop people from being able to click on the buttons and textboxes if the RelativeLayout is visible.
You will need to consume the click. Find yourRelativeLayout and set an OnClickListener on it:
yourRelativeLayout.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { }
});
In the xml file
android:clickable="false"
To do it in code:
LinearLayoutItem.setClickable(false);
I have a ListView with custom list items. Each list item consists of 2 linear layouts one next to other.
LinearLayout 1 | LinearLayout 2 |
I've declared state list drawables for both LinearLayouts where in state_pressed I'm changing the background of the LinearLayout.
And here comes the issue - When the user taps on the LinearLayout2 only the background of LinearLayout2 should be changed, the background of LinearLayout1 should remain unchanged. On the other hand, when the user taps on LinearLayout1, only the background of LinearLayout1 should be changed. But now when the user taps on either of both LinearLayouts, both of them change their background.
The behaviour on tap on LinearLayout2 should be as onListItemClick() while when the user taps on LinearLayout1 a Dialog should appear (if this matters).
Any ideas how could I solve the background change issue? I've tried playing with focusable and clickable options. If i set clickable=true to both LinearLayouts, the children (TextViews) of LinearLayout2 do not change their colour (the TextViews should change their text colour).
Thank you!
This is because when using a list view you have to change some tags in XML to make the background transparent so that it will correctly work with your back ground.
Add this to your ListView XML code.
android:cacheColorHint="#00000000"
To set the ListView's background to transparent.
Well I think a single solution if you are using BaseAdapter as extends
First give unique Id to both those Layouts in you xml file and add
android:clickable="true"
In your method
public View getView(int position, View convertView, ViewGroup parent) {
when your are getting those views like
holder.layout1_name=(LinearLayout)view.findViewById(R.id.layout1);
holder.layout1_name.setOnClickListener( clicklayout1);
holder.layout2_name=(LinearLayout)view.findViewById(R.id.layout2);
holder.layout2_name.setOnClickListener( clicklayout2);
Add click listener on them
private OnClickListener clicklayout1 = new OnClickListener() {
public void onClick(View v) {
//Do what you want to do here
}
};
private OnClickListener clicklayout2 = new OnClickListener() {
public void onClick(View v) {
//Do what you want to do here
}
};
May be this may help you
My issue is that I have a main screen, and I would like to dynamically spawn a view under it with a button click, then slide the main view off the screen revealing the view below it. I've accomplished this, but I feel like there's got to be a better way. The way I've done it is very limited in that you can't just spawn views over and over again under the main.
My main XML file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<RelativeLayout
android:id="#+id/subpage"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
</RelativeLayout>
<RelativeLayout
android:id="#+id/homescreen"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/homebg"
>
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
I've deleted some unnecessary stuff. This is what's important. Notice the first child of the main layout is a relative layout with the id "subpage." As it is I use java to inflate another layout into the subpage layout when a button is clicked then I animate the "homescreen" layout off the screen. It seems like I shouldn't have to have the subpage declared in advance though. I guess my question is, is there a way to dynamically declare a new child layout underneath an existing layout?
=======================================================================
Edit: Part 2 of question
I'm trying to use addView and the app crashes. This is the code I use to try to add a view and inflate my xml into it. In the code below subview is a ViewGroup because as I understand it you can only inflate into ViewGroups, not regular views. Also 'activity' is defined at the top of the class as 'private Activity activity = this'. Any ideas what could be causing the crash?
btnHelp.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
subView = (ViewGroup)new View(getApplicationContext());
mainScreen.addView(subView,1);
LayoutInflater inflater = activity.getLayoutInflater();
inflater.inflate(R.layout.help, subView);
}
});
=======================================================================
Edit: Part 3 of question
So one more issue. Everything works great as far as inflating and sliding off. However, the view that is inflated has a button in it. I'm trying to assign a listener to that button, but it doesn't seem to work. I'm doing it by adding the listener to the button after the layout inflater is called in the btnHelp I've been working on. Here's the code:
btnHelp.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
LayoutInflater inflater = activity.getLayoutInflater();
mainScreen.addView(inflater.inflate(R.layout.help, null),0);
homeScrn.startAnimation(slideLeftOut);
btnBackHome = (ImageView)findViewById(R.id.backMenuBtn);
btnBackHome.setOnClickListener(goHome);
}
});
goHome is a handler I've defined below this as such:
private OnClickListener goHome = new OnClickListener(){
public void onClick(View v) {
Log.d("ClickEvent: ","btnBackHome Clicked");
homeScrn.startAnimation(slideRightIn);
}
};
When I click the button referenced by btnBackHome it doesn't do anything. I'm just not sure if it's because the listener isn't actually being assigned, something is keeping the button from actually being clicked, or something else.
Call addView() on the RelativeLayout to add children to it, where the children are either inflated (getLayoutInflater().inflate()) or constructed directly in Java.
Also, you might consider using a ViewFlipper, considering that it does what you're seeking (animated transition from child to child, with only one child visible at a time in the steady state), perhaps with less code.
The default animation when starting a new Activity is a sliding animation.. why not just separate your "homescreen" and "subpage" into 2 different XML files and 2 Activities?
I have quite a complicated ListView. Each item looks something like this:
> LinearLayout (vertical)
> LinearLayout (horizontal)
> include (horizontal LinearLayout with two TextViews)
> include (ditto)
> include (ditto)
> TextView
> HorizontalScrollView (this guy is my problem)
> LinearLayout (horizontal)
In my activity, when an item is created (getView() is called) I add dynamic TextViews to the LinearLayout inside the HorizontalScrollView (besides filling the other, simpler stuff out). Amazingly, performance is pretty good.
My problem is that when I added the HorizontalScrollView, my list items became unclickable. They don't get the orange background when clicked and they don't fire the OnItemClickedListener I have set up (to do a simple Log.d call).
How can I make my list items clickable again?
Edit: setting android:descendantFocusability="blocksDescendants" on the topmost LinearLayout seems to work. I'd like to know if there are other ways, though: what if I want focusable items in my list items?
Using android:descendantFocusability="blocksDescendants" on the topmost LinearLayout did the trick. Elements inside can still be made "clickable", they're just not focusable (i.e. you can't click them on a non-touchscreen device). Good enough for me.
when i applied HorizontalScrollView to my TableLayout scrolling is working fine but unable to click on list item
My layout is as follwos
Linearlayout
HorizontalScrollView
TableLayout
.........
/TableLayout
/HorizontalScrollView
/LinearLayout
i applied android:descendantFocusability="blocksDescendants" to my top most linearlayout Any Help
android:descendantFocusability="blocksDescendants"
didn't help for me.
So
So, i realized listener patern.
public interface EventListItemOnClickListener {
public void itemClicked();
}
And in adapter notify all listeners
private List<EventListItemOnClickListener> listeners;
protected void notifyOnClick(int position){
for(int i=0; i<listeners.size();++i)
listeners.get(i).itemClicked((Event)events.get(position));
}
...
#Override
public void onClick(View v) {
notifyOnClick(position);
}
...