W mojej aplikacji w widoku przewijania korzystam z widoku listy. Ale widok listy nie jest przewijany. Czy ktoś może mi zasugerować, co powinienem zrobić? Szukałem go i dowiadywałem się, że widok listy nie przewija w obrębie widoku przewijania.
Jakieś rozwiązanie?Funkcja przewijania widoku list w widoku przewijania
Odpowiedz
Można utworzyć własny widok listy i ustawić opcję rozwijania na fałsz. Oto próbka klasa
public class ExpandableHeightListView extends ListView {
boolean expanded = false;
public ExpandableHeightListView(Context context) {
super(context);
}
public ExpandableHeightListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ExpandableHeightListView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
public boolean isExpanded() {
return expanded;
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// HACK! TAKE THAT ANDROID!
if (isExpanded()) {
int expandSpec = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public void setExpanded(boolean expanded) {
this.expanded = expanded;
}
}
Można użyć takiego twoi activity.clas
ExpandableHeightListView listview = (ExpandableHeightListView) findViewById(R.id.list);
listview.setExpanded(true);
w pliku układ można wykorzystać ExpandableHeightListView w miejscu widoku listy w widoku przewijania. Będzie przewijać.
Jaki jest sens używania ListView, jeśli nie pozwalasz na recykling produktów? Lepiej wtedy użyj pionowego LinearLayout. – BladeCoder
Nie umieszczaj widoku listy wewnątrz przewijania.
Listview już obsługuje przewijanie, więc nie musi znajdować się wewnątrz przewijania.
Powinieneś zmienić swoje układy, aby to odzwierciedlić.
Wyklucza ListView z ScrollView, ponieważ ListView ma już mechanizm przewijania.
To jest jak formularz, więc nie mogę wykluczyć listView z widoku przewijania. – Sandy
Nie wiem dlaczego Ucieczka od problemu rozwiązuje maksymalne głosowanie: P – IronManGill
@IronManGill zazdrosny? : P –
Zakładam, że masz wyjątkowy przypadek, tak jak to zrobiłem, kiedy musiałem to zrobić. Mam klasy pomocnika, który wygląda tak:
public class ScrollViewListHelper {
public static void getListViewSize(ListView myListView) {
ListAdapter myListAdapter = myListView.getAdapter();
if (myListAdapter == null) {
//do nothing return null
return;
}
//set listAdapter in loop for getting final size
int totalHeight = 0;
for (int size = 0; size < myListAdapter.getCount(); size++) {
View listItem = myListAdapter.getView(size, null, myListView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
//setting listview item in adapter
ViewGroup.LayoutParams params = myListView.getLayoutParams();
params.height = totalHeight + (myListView.getDividerHeight() * (myListAdapter.getCount() - 1));
myListView.setLayoutParams(params);
// print height of adapter on log
Log.i("height of listItem:", String.valueOf(totalHeight));
}
}
a następnie po zainicjować adapter dla ListView zrobić to:
ScrollViewListHelper.getListViewSize(listViewMeasurements);
ListView Wewnątrz Scroll View nie będzie działać . Połóż to poza tym. Ponieważ oba mają przewijaną funkcję, więc przewijanie nie zadziała, kiedy się połączą.
import android.content.Context;
import android.widget.ListView;
public class MyListView extends ListView {
public MyListView(Context context) {
super(context);
}
public MyListView(Context context, android.util.AttributeSet attrs) {
super(context, attrs);
}
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
użycie tego
użyć tej klasy.
public class CustomScrollView extends ScrollView {
public CustomScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public boolean onTouchEvent(MotionEvent ev) {
return true;
}
public boolean onInterceptTouchEvent(MotionEvent ev) {
return false;
}
}
A w układzie xml zmienić tag Scrollview z nazwą pakietu i klasie CustomScrollView. tj. zmienić na com.test.CustomScrollView.
Wewnątrz ciebie Aktywność uzyskaj identyfikator niestandardowego widoku przewijania i dołącz ten kod.
private int currentX, currentY;
private CustomScrollView customScrollView;
customScrollView.setSmoothScrollingEnabled(true);
customScrollView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
switch(event.getAction()){
case MotionEvent.ACTION_DOWN: {
currentX = (int) event.getRawX();
currentY = (int) event.getRawY();
break;
}
case MotionEvent.ACTION_MOVE: {
@SuppressWarnings("unused")
int x2 = (int) event.getRawX();
int y2 = (int) event.getRawY();
customScrollView.scrollBy(0 , currentY - y2);
currentY = y2;
break;
}
case MotionEvent.ACTION_UP: {
break;
}
}
return true;
}
});
Widok przewijania „zjada” wszystkie poprawki ... Należy unikać wstawiania element ListView przewijania() do innego elementu przewijania (zobacz przewijania), twój użytkownik może zwariować.
W takich przypadkach używam LinearLayout zamiast ListView i nadmuchać do niej CustomView stworzony do reprezentowania każdego elementu listy, tutaj jest przykładem, spadła do mnie zapytać się więcej:
LinearLayout containerLinearLayout= (LinearLayout)findViewById(R.id.containerLinearLayout);
containerLinearLayout.removeAllViews();
for(int i=0;i<array.length();i++){
JSONObject convocazione=array.getJSONObject(i);
View child = getLayoutInflater().inflate(R.layout.list_element_layout,null);
TextView txtDettaglioLuogo=(TextView)child.findViewById(R.id.txtDettaglioLuogo);
TextView txtOra=(TextView)child.findViewById(R.id.txtOra);
txtOra.setText("text");
txtData.setText("more text");
containerLinearLayout.addView(child);
}
Don 't umieścić listView wewnątrz ScrollView. Należy przeczytać odpowiedź Romain Guy i komentarz powyżej:
How can I put a ListView into a ScrollView without it collapsing?
Można wykluczyć ListView z widoku przewijania. Jeśli chcesz mieć "listę" wewnątrz scrollView, możesz użyć LinearLayout.Coś takiego:
public class MyListLayout extends LinearLayout implements
View.OnClickListener {
private Adapter list;
private View.OnClickListener mListener;
public MyListLayout(Context context) {
super(context);
}
public MyListLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public EvernoteListLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onClick(View v) {
if (mListener!=null)
mListener.onClick(v);
}
public void setList(Adapter list) {
this.list = list;
//Popolute list
if (this.list!=null){
for (int i=0;i<this.list.getCount();i++){
View item= list.getView(i, null,null);
this.addView(item);
}
}
}
public void setmListener(View.OnClickListener mListener) {
this.mListener = mListener;
}
}
// Create ArrayAdapter
MyListAdapter mListAdapter = new MyListAdapter();
MyListLayout mLay = (MyListLayout) findViewById(R.id.box_list_ev);
if (mLay != null) {
mLay.setList(mListAdapter);
}
, więc możemy po prostu trzeba umieścić 'Mylistlayout' będzie działać jak listview? –
W końcu dostałem rozwiązanie problemu z przewijaniem Mam niestandardową klasę scrollview do zarządzania przewijaniem.
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ScrollView;
public class VerticalScrollview extends ScrollView{
public VerticalScrollview(Context context) {
super(context);
}
public VerticalScrollview(Context context, AttributeSet attrs) {
super(context, attrs);
}
public VerticalScrollview(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
switch (action)
{
case MotionEvent.ACTION_DOWN:
Log.i("VerticalScrollview", "onInterceptTouchEvent: DOWN super false");
super.onTouchEvent(ev);
break;
case MotionEvent.ACTION_MOVE:
return false; // redirect MotionEvents to ourself
case MotionEvent.ACTION_CANCEL:
Log.i("VerticalScrollview", "onInterceptTouchEvent: CANCEL super false");
super.onTouchEvent(ev);
break;
case MotionEvent.ACTION_UP:
Log.i("VerticalScrollview", "onInterceptTouchEvent: UP super false");
return false;
default: Log.i("VerticalScrollview", "onInterceptTouchEvent: " + action); break;
}
return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
super.onTouchEvent(ev);
Log.i("VerticalScrollview", "onTouchEvent. action: " + ev.getAction());
return true;
}
}
Sprawdź kod źródłowy onMeasure z ListView, można zauważyć, że jeśli wysokość measureSpec jest nieokreślona wtedy wysokość ListView jest wysokość tylko jedna pozycja plus kilka obicia, patrz poniżej:
if (heightMode == MeasureSpec.UNSPECIFIED) {
heightSize = mListPadding.top + mListPadding.bottom + childHeight +
getVerticalFadingEdgeLength() * 2;
}
Możemy więc w prosty sposób zmienić wysokość właściwości SpecMode na AT_MOST, a wysokość wysokości jest lewym rozmiarem wysokości jego obiektu nadrzędnego. Poniżej przedstawiono rozwiązanie:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec),
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
Chociaż ten fragment kodu może rozwiązać pytanie, [w tym wyjaśnienie] (http://meta.stackexchange.com/questions/114762/explaining-entirely-code-ans -answers) naprawdę pomaga poprawić jakość twojego posta. Pamiętaj, że odpowiadasz na pytanie przeznaczone dla czytelników w przyszłości, a te osoby mogą nie znać powodów sugestii dotyczących kodu. – DimaSan
Jakieś specjalne powody dodania przewijania do już przewiniętego włączonego widoku listy? –