2016-05-16 11 views
2

我在Viewpager裏面使用了listview,我需要根據child設置ListView的高度,當用戶滾動到Listview的最後位置時我需要添加新的Items。但問題是,當我動態設置列表視圖高度時,它使當前列表視圖項目可見(或選定)。這就是爲什麼自動獲取(調用方法來獲取數據)的原因。 守則如下:在Listview中正確檢測setOnScrollListener在設置Listview高度之後正確地使用

int index = lvNetwork.getFirstVisiblePosition(); 
    View v = lvNetwork.getChildAt(0); 
    int top = (v == null) ? 0 : v.getTop(); 

    adapter = new NetworkAdapter(activity, R.layout.network_custom_row, networkDataArrayList); 
    adapter.notifyDataSetChanged(); 
    lvNetwork.setAdapter(adapter); 
    Utils.setlistViewHeight(lvNetwork, activity); 

    lvNetwork.setSelectionFromTop(index, top); 

    lvNetwork.setOnScrollListener(new AbsListView.OnScrollListener() { 
     @Override 
     public void onScrollStateChanged(AbsListView view, int scrollState) { 

     } 

     @Override 
     public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 

      int finalItem = firstVisibleItem + visibleItemCount; 

      Log.d("dataCalling", "visible " + finalItem); 
      Log.d("dataCalling", "total " + totalItemCount); 

      if (finalItem == totalItemCount) { 

       if (preLast != finalItem) { 
        preLast = finalItem; 
        Log.d("dataCalling", String.valueOf(totalItemCount)); 
        Log.d("dataCalling", "Page " + nextid); 
        progressBar.setVisibility(View.VISIBLE); 

         getNetworkFeed(); 

       } 
      } 
     } 
    }); 

內utils的setlistviewHeight方法,

public static void setlistViewHeight(ListView listView, Context context) { 

    ListAdapter myListAdapter = listView.getAdapter(); 

    if (myListAdapter == null) { 
     return; 
    } 

    int totalHeight = 0; 
    for (int size = 0; size < myListAdapter.getCount(); size++) { 

     View listItem = myListAdapter.getView(size, null, listView); 
     if (listItem instanceof ViewGroup) 
      listItem.setLayoutParams(new RelativeLayout.LayoutParams(
        RelativeLayout.LayoutParams.WRAP_CONTENT, 
        RelativeLayout.LayoutParams.WRAP_CONTENT)); 

     WindowManager wm = (WindowManager) context 
       .getSystemService(Context.WINDOW_SERVICE); 
     Display display = wm.getDefaultDisplay(); 
     @SuppressWarnings("deprecation") 
     int screenWidth = display.getWidth(); 
     int listViewWidth = screenWidth - 65; 
     int widthSpec = View.MeasureSpec.makeMeasureSpec(listViewWidth, 
       View.MeasureSpec.AT_MOST); 
     listItem.measure(widthSpec, 0); 

     totalHeight += listItem.getMeasuredHeight(); 
    } 

    ViewGroup.LayoutParams params = listView.getLayoutParams(); 
    params.height = totalHeight 
      + (listView.getDividerHeight() * (myListAdapter.getCount())); 
    listView.setLayoutParams(params); 
    listView.requestLayout(); 
} 

***此代碼的工作好,如果我不需要動態設置列表視圖高度。 我應該在這裏改變什麼,使其工作或任何替代解決方案來獲得慾望的結果?

任何幫助將不勝感激。

+0

你可以發佈內部Utils.setlistViewHeight(lvNetwork,活動)的代碼; ? –

+0

發佈,請檢查。 – Exigente05

+0

日誌更正? visibleItemCount有一個正確的值? – Groco

回答

2

但問題是,當我設置列表視圖高度動態的動態地使當前列表視圖項可見

設置高度是沒有問題的。相反,問題在於你正在通過計算列表中每個項目的高度來將listview的高度設置爲listview的最大可能高度。所以會發生什麼是列表視圖的所有項目將立即進行填充,然後在列表將保持膨脹(注:無景觀回收現在會發生)。

這就是爲什麼越來越(調用方法獲取數據)自動

調用正在發生,因爲您正在根據列表中的項目總數設置listview的高度。發生這種情況的原因是,在任何給定的時間點,listview中的所有元素都將處於可見狀態。這意味着你的條件

if (finalItem == totalItemCount){} 

將永遠是正確的,因爲你的visibleItemCount永遠是totalItemCount使你總是最後一個項目等於totalItemCount。 (你可以通過調試你的應用程序來驗證這一點)。

我該如何改變以使其工作或獲得願望結果的任何替代解決方案?

我能想到的是設置的ListView的高度最好的解決方法當且僅當由你所有項目的高度的基礎上calcuated總高度比屏幕的高度較小。否則,將列表視圖的高度設置爲MATCH_PARENT

ViewGroup.LayoutParams params = listView.getLayoutParams(); 
     Display display = getWindowManager().getDefaultDisplay(); 
     Point size = new Point(); 
     display.getSize(size); 
     int height = size.y; 
     if(totalHeight > height){ 
      params.height = ViewGroup.LayoutParams.MATCH_PARENT; 
     }else { 
      Log.d("", ""); 
      params.height = totalHeight 
        + (listView.getDividerHeight() * (myListAdapter.getCount())); 
     } 

所以這個代碼將禁止撥打列表視圖的所有視圖變得可見,因此onScroll visibleItemCount您會收到,會在沒有任何項目的當前可見。

+0

當在任何時間點填充的所有項目都是毫無意義的時,使用ListView。 –

+0

工作,但在其他地方listview顯示只有一行。你能幫我多點嗎? – Exigente05

0

Ankit已經向你解釋了你的代碼有什麼問題,讓我與你分享一個替代解決方案。

當你已經填充它的項目而不是使用listview時,最好使用scrollview並動態地添加項目。ScrollView沒有滾動監聽器,所以我們將其定製爲一個。

MyScrollView.Java

public class MyScrollView extends ScrollView { 

public interface OnScrollListener { 
    void onScrollChanged(int l, int t, int oldl, int oldt); 
} 

private OnScrollListener onScrollListener; 

public OnScrollListener getOnScrollListener() { 
    return onScrollListener; 
} 

public void setOnScrollListener(OnScrollListener onScrollListener) { 
    this.onScrollListener = onScrollListener; 
} 

public MyScrollView(Context context) { 
    super(context); 
} 

public MyScrollView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
} 

public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
} 

@Override 
protected void onScrollChanged(int l, int t, int oldl, int oldt) { 
    super.onScrollChanged(l, t, oldl, oldt); 

    if (onScrollListener != null) { 
     onScrollListener.onScrollChanged(l, t, oldl, oldt); 
    } 
} 
} 

我們使用scrolllistener在活動這樣的 -

import android.graphics.Rect; 
import android.os.AsyncTask; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.widget.LinearLayout; 
import android.widget.ProgressBar; 
import android.widget.TextView; 

public class NewScrollActivity extends AppCompatActivity { 

private MyScrollView scrollView; 
private LinearLayout container; 
private ProgressBar progressBar; 
int maxItem = 20; 
private View lastItemView; 
boolean alreadyExecutingRequest = false; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_new_scroll); 

    progressBar = (ProgressBar) findViewById(R.id.progressBar); 
    scrollView = (MyScrollView) findViewById(R.id.scrollView); 
    scrollView.setOnScrollListener(scrollListener); 
    container = (LinearLayout) findViewById(R.id.container); 

    addItemsAsynchronously(); 
} 

private MyScrollView.OnScrollListener scrollListener = new MyScrollView.OnScrollListener() { 
    @Override 
    public void onScrollChanged(int l, int t, int oldl, int oldt) { 

     if (lastItemView != null && !alreadyExecutingRequest) { 
      Rect scrollBounds = new Rect(); 
      scrollView.getHitRect(scrollBounds); 
      if (lastItemView.getLocalVisibleRect(scrollBounds)) { 
       // Any portion of the lastitem view, even a single pixel, is within the visible window 
       addItemsAsynchronously(); 
      } 
     } 
    } 
}; 

private void addItemsAsynchronously() { 

    new AsyncTask<Void,Void,Void>() { 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      progressBar.setVisibility(View.VISIBLE); 
      alreadyExecutingRequest = true; 
     } 

     @Override 
     protected Void doInBackground(Void... voids) { 
      try { 
       Thread.sleep(3000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      return null; 
     } 

     @Override 
     protected void onPostExecute(Void aVoid) { 
      super.onPostExecute(aVoid); 

      progressBar.setVisibility(View.GONE); 
      addItemsToContainer(); 
      alreadyExecutingRequest = false; 
     } 


    }.execute(); 
} 

private void addItemsToContainer() { 
    int lastAddedItem = container.getChildCount(); 
    for (int i=lastAddedItem;i<maxItem;i++) { 
     View view = LayoutInflater.from(this).inflate(R.layout.new_item, null); 
     TextView textView = (TextView) view.findViewById(R.id.textView); 
     textView.setText("Item - " + i); 

     container.addView(view); 
    } 
    lastItemView = container.getChildAt(container.getChildCount() -1); 
    maxItem+=10; 
} 
} 

這裏我們所做的事情是我們檢查與滾動視圖邊界約束的最後一個項目,所以它的觀點可見,那麼我們在底部,所以添加更多的項目。

activity_new_scroll.xml

<?xml version="1.0" encoding="utf-8"?> 
<com.sj.textinputlayout.MyScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/scrollView" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context="com.sj.textinputlayout.NewScrollActivity"> 

    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="vertical"> 

     <LinearLayout 
      android:id="@+id/container" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:orientation="vertical" /> 

     <ProgressBar android:id="@+id/progressBar" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:visibility="gone" 
      android:layout_gravity="center_horizontal"/> 
    </LinearLayout> 

</com.sj.textinputlayout.MyScrollView> 

new_item.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" android:layout_width="match_parent" 
    android:padding="10dp" 
    android:layout_height="wrap_content"> 

    <TextView android:id="@+id/textView" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" /> 
</LinearLayout>