ListView items not clickable with HorizontalScrollView inside - android

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);
}
...

Related

RecyclerView does not fully expand to show all elements

I've created an EditText, a Button and a RecyclerView (composed of 1 TextView and 1 ImageView children) to add TextViews that looks like this . In the EditText at the top, users may enter text and hit the + button. This adds their text to a List(String) which is used to update the RecyclerView. The user may hit the x at the right to delete an entry from the RecyclerView. Here is an image of the overall fragment layout
The issue, which you can see in the image, is that after a few submissions, the RecyclerView stops expanding and remains at a fixed size (notice the small blip in the bottom right). You may scroll in the RecyclerView to view the items, items are still added to it, but it will not expand to the full size (the one in the image has 20+ items). If I delete an item, the height grows for some reason but it still won't display all elements and it shrinks back when I add a new item.
Things I've tried
Here is the RecyclerView code. The heirarchy goes
<LinearLayout>
<ScrollView>
<LinearLayout>
<RecyclerView />
</LinearLayout>
</ScrollView>
</LinearLayout>
All heights and widths are set to match parent, all orientations to vertical:
<android.support.v7.widget.RecyclerView
android:id="#+id/ingredientsRecyclerView"
android:layout_marginTop="4dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
>
The code to add an entry to the RecyclerView (outside of the adapter):
ingredientsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (ingredientsText.getText().toString().length() > 0) {
mIngredients.add(ingredientsText.getText().toString());
ingredientsText.setText("");
mAdapter.notifyDataSetChanged();
mRecyclerView.setBackgroundResource(R.drawable.rounded_edittext);
}
}
});
And, finally, the code to delete an entry from the RecyclerView (inside the RV adapter):
cancelImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mIngredients.remove(getAdapterPosition());
mAdapter.notifyItemRemoved(getAdapterPosition());
mAdapter.notifyItemRangeChanged(getAdapterPosition(), mIngredients.size());
if(mAdapter.getItemCount() == 0)
mRecyclerView.setBackgroundResource(0);
}
});
Any assistance would be GREATLY appreciated, as I can't figure this out for the life of me!
use NestedScrollView instead of ScrollView and setNestedScrollEnabled(false) on the RecyclerView
k0sh is absolutely right. Just to add, use the full class name, which is android.support.v4.widget.NestedScrollView (make sure you have the v4 support library in your build.gradle file), or Android won't find NestedScrollView class. Source: Error inflating class - NestedScrollView - class not found
Use NestedScrollView instead of ScrollView and on your NestedScrollView set
isNestedScrollingEnabled = false

Make LinearLayout clickable - Colorize background like the default for ListView

Hello my name is Fabian and at the moment I try to programming an Android App.
I have a ListView with some items and above this ListView I added a LinearLayout, which I want to make clickable, to add items to the ListView.
If I touch one entry in the ListView the item gets colorized with the default color, a light grey. I like to have this behaviour for my LinearLayout, too.
I know how to get the LinearLayout clickable.
I did this by
android:clickable="true"
android:onClick="addProject"
Also I know how to define the backgroundcolor, but I don't know how I can pass the default colors from android of the ListView (android:listSelector) to the LinearLayout.
I tested to define
android:background="?android:attr/listChoiceBackgroundIndicator"
but in that case the LinearLayout gets colorized blue and only if I touch it, it gets the right color.
I hope you can help me, to pass the default color of a ListView to a LinearLayout.
Remove below line from your LinearLayout
android:onClick="addProject"
and add an id to a LinearLayout,
android:id="#+id/linear_layout"
From JAVA add this,
LinearLayout layout = (LinearLayout) findViewById(R.id.linear_layout);
layout.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v) {
Toast.makeText(this, "Layout Clicked", Toast.LENGTH_LONG).show();
}
});

ClickListener in ScrollView intercepts scrolling

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.

ListView item selection

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

How can I get my ListView to scroll?

I have a quite complex View build-up, and as a part of that, I have a ListView inside a LinearLayout within a ScrollView (and quite a lot more components, but they do not matter in this issue).
Now the whole activity scrolls nicely as it should, but the ListView has a limited height, and when the Items inside it surpass the height, the disappear of my screen. I've tried to place the ListView inside it's own ScrollView, but this doesn't work. When I try to scroll on the ListView, the main ScrollView is selected and my screen scrolls instead of the ListView.
My question may sound easy, but I haven't been able to fix this... Is it possible to make the ListView scrollable aswell?
The relevant XML:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:id="#+id/GlobalLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView android:id="#+id/EndpointList"
android:choiceMode="multipleChoice"
android:layout_height="175dip"
android:layout_width="fill_parent" />
</LinearLayout>
</ScrollView>
Instead of ListView with other layouts inside ScrollView create one ListView with header and footer.
Add views that should be above ListView as a header:
addHeaderView(View v)
and that below as a footer:
addFooterView(View v)
Put everything what should be above ListView to header of ListView and the same with footer.
LayoutInflater inflater = LayoutInflater.from(this);
mTop = inflater.inflate(R.layout.view_top, null);
mBottom = inflater.inflate(R.layout.view_bottom, null);
list.addHeaderView(mTop);
list.addFooterView(mBottom);
// add header and footer before setting adapter
list.setAdapter(mAdapter);
In result you'll get one scrollable view.
Actually, the way that I have it set up is really working... Placing a ListView in a LinearLayout within a ScrollView. Just avoid that the ListView is the direct child of the ScrollView, and it will work out just fine...
Just be aware that if there aren't enough items in the ListView to fill it so it goes 'off screen', that it won't scroll (kind of logically though). Also note that when you have enough items to scroll through, you need to keep pressing on an item in the ListView to make it scroll, and half of the time, focus is given to the global scrollview in stead of the ListView... To avoid this (most of the time), keep pressing on the most top or most down item, depending on which way you want to scroll.This will optimize your chance to get focus on your ListView.
I've made a video that it is possible, am uploading it now to YouTube...
Video is http://www.youtube.com/watch?v=c53oIg_3lKY. The quality is kinda bad, but it proves my point.
Just for a global overview, I used the ScrollView to be able to scroll my entire activity, the LinearLayout for the Activity's layout, and the ListView to, well, make the list...
I would like to just note something for the video
The listview is working once every x touches not because you placed it inside a linearlayout but because you are touching the the divider...
the scrollview will then consider that the place you touched does not have children to dispatch the motionevent to... so it calls the super.dispatchTouchEvent which is in this case the View.dispatchTouchView hence the listview.onTouchEvent.
When you touch inside a row the scrollview which is really a viewgroup will send the dispatch to the children in your case the textview and never calls the one of the view so the listview do not scroll.
Hope my explanation was clear enough to point out why is it not working.

Categories

Resources