I have been trying to hack a ListView into a ScrollView. As many threads have pointed out, this is a very bad practice (see How can I put a ListView into a ScrollView without it collapsing?). I am currently measuring the height of my ListView and fixing its size using the solution proposed here (https://stackoverflow.com/a/3495908/924217), which works perfectly for equal height rows, but is measured incorrectly for variable height (reports min height for all rows). For quick and dirty fix, does anyone know how to measure the height properly for variable height rows?
More appropriately, can anyone point me to a good workaround using LinearLayouts. I am trying to use a ListView because I have items which I need to dynamically add and remove to the list. I cannot think of any convenient ways of doing this without adapters and the other niceties appropriated by a ListView. Can someone help me find an example of this being handled properly? Also, are there any open source projects which cover this? I have seen many people asking similar questions with little non-hacky resolve.
I would recomend that you should use listfragment so that you can dynamically add/remove items.
here parentScroll = your main scrollview and childScroll = your listview
parentScroll.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
Log.v("PARENT", "PARENT TOUCH");
findViewById(R.id.child_scroll).getParent()
.requestDisallowInterceptTouchEvent(false);
return false;
}
});
childScroll.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
Log.v("CHILD", "CHILD TOUCH");
// Disallow the touch request for parent scroll on touch of
// child view
v.getParent().requestDisallowInterceptTouchEvent(true);
return false;
}
});
Related
can we have ListView inside ExpandableListView so that I can have group level first and then array of child (listView). i already finish from listview classes and it works perfectly!
but how to call each group in expandable list view to display list view (layout)! and get the correct child !
please can any one help !
thanks.
Actually you can put a scrollable view (e.g. your ListView) inside another scrollable view (e.g. your ExpandableListView) and make the former scrollable in the following way:
listView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// disallow the onTouch for your scrollable parent view
v.getParent().requestDisallowInterceptTouchEvent(true);
return false;
}
});
Yes you can! But the real thing is to create a listView in a expandableView.
Here is the trick: https://www.captechconsulting.com/blogs/android-expandablelistview-magic
Please take a look at this question which was asked two days ago. The user there was trying to put a custom view, derived from ListView into ExpandableListView. My answer to that question applies to your case as well, so I'll quote it:
You can't do that because you can't put a scrollable view(ListView)
into another scrollable view(ExpandableListView). The reason is that
the parent will consume all the touch events and they will never reach
the child. ExpandableListView will scroll, but the ListView will never
know that scrolling took place.
I have an expandable list with all groups always expanded and the groups not collapsable. The problem is that even if I made the groups to not collapse when I click on them the "select" effect is still visible and I don't want it to be visible. How can I do that?
Any answer would be appreciated.
Thanks
I have figure out myself after all how to do that :D I have put this code:
view.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent event) {
return true;
}
});
in the adapter of the ExpandableList in the getGroupView method. And now it's working.
Normally when you click on the group name, it collapses automatically. Here is an example of expandableListView. Moreover, I could hardly make any comment unless I see what you did.
I'm using a GridView for a game board. Recently some users have had problems with the board scrolling vertically (on Samsung Galaxy / Vibrant phones running 2.2) -- This bug does not occur on my Nexus One.
One user produced some screenshots of the problem.
How could I lock the GridView in place? Is there a way to disable scrolling?
Try to add or override setOnTouchListener for GridView,
then in onTouch method you can use code like this to
make gridView not scrollable
Java
gridView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return event.getAction() == MotionEvent.ACTION_MOVE;
}
});
Kotlin
gridView.setOnTouchListener { v, event ->
event.action == MotionEvent.ACTION_MOVE
}
You can try setEnabled(false), although it might have other side effects. GridView is really not meant to be used the way you are using it. You should create your own custom view or layout. You could also use a TableLayout.
In the app I am currently building I have been synchronizing ListViews with unbound Lists of data via BaseAdapter. This has been working so far but now I need to have a list of data inside a ScrollView. The problem with putting a ListView inside a ScrollView is that both views scroll and it make the activity difficult to navigate. From what I've read online the consensus seems to be that ListViews should never be put inside of scroll views for this reason, and that a LinearLayout or TableLayout should be used instead.
My quesion is this: Can any one tell me either how to get rid of the Scrolling Feature on a ListView or how to synchronize a List of data with a LinearLayout or a TableLayout through an adapter?
You could make your own custom ListView component and then override the dispatchTouchEvent() method:
#Override
public boolean dispatchTouchEvent(MotionEvent event)
{
int action = event.getAction();
if (!scrollEnabled) {
event.setAction(MotionEvent.ACTION_CANCEL);
super.dispatchTouchEvent(event);
return true;
}
return super.dispatchTouchEvent(event);
}
In these kinds of situations though, what I've done in the past is have a separate vertical LinearLayout for my list and manually added TextViews via code to it, making it look similar to a listview.
This question is a bit awkward. Is it possible to transfer the touch focus of one view to another? Basically, say that you have a view that picks up the first ACTION_DOWN touch event, and then immediately wants to transfer the focus for all touch events to another view to handle with it's onTouchEvent(MotionEvent event). I thought that doing the following would make it work, but it didn't:
#override
public boolean onTouchEvent(MotionEvent) {
this.clearFocus();
anotherView.setFocusableInTouchMode(true);
anotherView.requestFocus();
}
Obviously, it seems to me that it just doesn't work that way. Could someone explain to me how I can go about doing something like this?
If it's still a bit difficult to understand my question, think about a regular button. When pressed, the button is highlighted (focused) and if you move your finger off the button but still keep your finger on the screen, the button becomes unfocused but still has control of the entire touch events (no other view can become focused even if you move over them). My question asks if it is possible to transfer this touch focus to another view to handle without having you to remove your finger off the screen.
Try below code might work
button1.setOnFocusChangeListener(new OnFocusChangeListener()
{
#Override
public void onFocusChange(View arg0, boolean hasFocus)
{
if(hasFocus)
button2.requestFocus();
}
});
The way I worked around this was to have a single view "harness" whose sole purpose was to pass on the touch information to the other classes, who would then do the processing. Note that ViewA and B don't actually have to be views and extend the view class. Its not an ideal solution, but I don't think it's possible to solve this problem with the current Android framework (ICS/JB).
class ViewHarness extends View{
public boolean onTouch(MotionEvent event){
if(ViewA is selected)
ViewA.onTouch(event);
else
ViewB.onTouch(event);
}