2016-05-16 5 views
2

私はリストビューの高さを子に基づいて設定する必要があるViewPage内でlistviewを使用しています。しかし、問題は、リストビューの高さを動的に設定して現在のリストビュー項目を表示(または選択)しているときです。そのため、(メソッドを呼び出してデータを取得する)ことが自動的に行われます。 コードは以下のとおりである:Utilsの、リストビューの高さを動的に設定した後、ListViewのsetOnScrollListenerが正しく検出されました。

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

内部

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(); 

       } 
      } 
     } 
    }); 

setlistviewHeight方法***私は動的にリストビューの高さを設定する必要がない場合、このコードは良い作品。 欲望の結果を得るためには、それを動作させるために何を変えるべきですか?

ご協力いただければ幸いです。

+0

あなたはUtils.setlistViewHeight(lvNetwork、活動)内のコードを投稿することができます。 ? –

+0

が掲載されました。ご確認ください。 – Exigente05

+0

ログは正しいですか? visibleItemCountに正しい値がありますか? – Groco

答えて

2

しかし、私は動的に作る現在のListView項目目に見える

が動的に高さを設定するには問題はありませんリストビューの高さを設定していたときに問題があります。むしろ、問題はリスト内の各項目の高さを計算することによって、リストビューの高さをリストビューの最大可能高さに設定することです。リストビューのすべてのアイテムが一度に読み込まれ、リスト内で膨らんだ状態になります(注:リサイクルは現在行われません)。

これは、getメソッドを呼び出すことで、自動的に

リスト内のアイテムの総数に基づいてリストビューの高さを設定しているため、コールが行われています。このために何が起こるかは、あなたのリストビュー内のすべての要素が任意の時点で可視状態になることです。あなたのvisibleItemCountは常にtotalItemCountに等しい常にあなたの最後の項目になりますtotalItemCountになりますので、あなたの状態を意味している

if (finalItem == totalItemCount){} 

は常にtrueになります。 (アプリをデバッグすることでこれを確認できます)。

欲望の結果を得るためには、それを動作させるために何を変更する必要がありますか?

私が考えることができる最高の解決策は、すべてのアイテムの高さに基づいて計算された高さの合計が画面の高さより小さい場合にのみリストビューの高さを設定することです。それ以外の場合は、リストビューの高さを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

は動作しましたが、他の場所では1行しか表示されないリストビューです。もう少し手伝ってもらえますか? – Exigente05

0

Ankitは既にあなたのコードの問題点について説明しましたが、別の解決方法をあなたに教えてください。

既にアイテムを入力しているときにリストビューを使用するのは良いことではなく、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を使用する - 私たちはscrollviewの境界を結合させた最後の項目をチェックしている何をしたかここで

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> 
関連する問題