当前位置: 首页 > 面试题库 >

无休止的滚动列表视图不起作用

汝志
2023-03-14
问题内容

我正在开发一个应用程序。在我的应用程序中,我正在使用listview显示json中的数据。所有数据完美显示。但是我想要的是先显示10个对象,然后显示加载项,然后显示其余10个。我的json响应如下。

{
 "interestsent":
  [
   {
    "interestsent_user_id":369,
    "name":"abc",
    "profile_id":"686317",
    "image":"",
    },
    {
    "interestsent_user_id":369,
    "name":"def",
    "profile_id":"686318",
    "image":"",
    },
    {
    "interestsent_user_id":369,
    "name":"ghi",
    "profile_id":"686319",
    "image":"",
    },
     {
    "interestsent_user_id":369,
    "name":"jkl",
    "profile_id":"686320",
    "image":"",
    },
    {
    "interestsent_user_id":369,
    "name":"mno",
    "profile_id":"686321",
    "image":"",
    },
    {
    "interestsent_user_id":369,
    "name":"pqr",
    "profile_id":"686322",
    "image":"",
    },
    .................
    .................
 ]
 }

Interestsent.java

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

    INTEREST_SENT_URL = "http://fshdfh.com/webservice/interestsent?version=apps&user_login_id=00";
    new GetData().execute("");
    listview = (ListView) findViewById(R.id.listview);
    Log.i("DATA", "page ::onCreate onCreate onCreate  ");
    mHandler = new Handler();
    listview.setOnScrollListener(new EndlessScrollListener() {
        @Override
        public void onLoadMore(int page, int totalItemsCount) {
            Log.i("DATA", "page :: " + page + " totalItemsCount :: "
                    + totalItemsCount);
            mProgressbar = new ProgressDialog(MainActivity.this);
            mProgressbar.setMessage("Loading...");
            mProgressbar.show();
            count++;
            if (count < maindata.size()) {
                if (adapter != null) {

                    if (!isLoadingMore) {
                        isLoadingMore = true;
                        mHandler.postDelayed(loadMoreRunnable, 1000);
                    }
                }
            }
        }
    });

}

Runnable loadMoreRunnable = new Runnable() {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        if (count < maindata.size()) {
            if (adapter != null) { 
                adapter.addAll(maindata.get(count));
                mHandler.removeCallbacks(loadMoreRunnable);
                isLoadingMore = false;
                if (mProgressbar.isShowing())
                    mProgressbar.dismiss();
            }
        }
    }
};

static <T> ArrayList<ArrayList<T>> chunkList(List<T> list, final int L) {
    ArrayList<ArrayList<T>> parts = new ArrayList<ArrayList<T>>();
    final int N = list.size();
    for (int i = 0; i < N; i += L) {
        parts.add(new ArrayList<T>(list.subList(i, Math.min(N, i + L))));
    }
    return parts;
}
private ProgressDialog mProgressbar;
public class GetData extends AsyncTask<String, String, String> {
    ArrayList<Integer> data = new ArrayList<Integer>();


    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        mProgressbar = new ProgressDialog(MainActivity.this);
        mProgressbar.setMessage("Loading...");
        mProgressbar.show();
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(String... params) {
        // TODO Auto-generated method stub
        ArrayList<ArrayList<Integer>> data = new ArrayList<ArrayList<Integer>>();
        ServiceHandler sh = new ServiceHandler();
        /*try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }*/
        /*for (int i = 0; i < 500; i++) {
            data.add(i);
        }

        return null;*/

        String jsonStr = sh.makeServiceCall(INTEREST_SENT_URL, ServiceHandler.GET);
        Log.d("Response: ", "> " + jsonStr);
        if (jsonStr != null) {
            try {
                JSONObject jsonObj = new JSONObject(jsonStr);
                // Getting JSON Array node
                interestsent = jsonObj.getJSONArray(INTEREST_SENT);
                // looping through All Contacts
                for (int i = 0; i < interestsent.length(); i++) {
                    JSONObject c = interestsent.getJSONObject(i);
                    // creating new HashMap
                   // HashMap<ArrayList<Integer> map = new  HashMap<Integer>();
                   HashMap<String, String> map = new HashMap<String, String>();
                    // adding each child node to HashMap key => value
                    map.put(INTEREST_USER_ID, c.getString(INTEREST_USER_ID));
                    map.put(INTEREST_SENT_NAME,c.getString(INTEREST_SENT_NAME));
                    map.put(INTEREST_SENT_PROFILE, c.getString(INTEREST_SENT_PROFILE));
                    map.put(INTEREST_SENT_IMAGE, c.getString(INTEREST_SENT_IMAGE));
                    map.put(INTEREST_SENT_CAST, c.getString(INTEREST_SENT_CAST));
                    map.put(INTEREST_SENT_AGE, c.getString(INTEREST_SENT_AGE)+" years");
                    map.put(INTEREST_SENT_LOCATION, c.getString(INTEREST_SENT_LOCATION));
                    // adding HashList to ArrayList
                    data.addAll(map);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        } else {
            Log.e("ServiceHandler", "Couldn't get any data from the url");
        }

        return data;
    }

    @Override
    protected void onPostExecute(String result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        maindata = chunkList(data, 50);
        Log.i("DATA", "maindata :: " + maindata.size());

        adapter = new CustomAdapterSent(maindata.get(count),
                MainActivity.this);
        listview.setAdapter(adapter);
        if (mProgressbar.isShowing())
            mProgressbar.dismiss();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

EndlessScroolListener.java

 public abstract class EndlessScrollListener implements OnScrollListener {
// The minimum amount of items to have below your current scroll position
// before loading more.
private int visibleThreshold = 5;
// The current offset index of data you have loaded
private int currentPage = 0;
// The total number of items in the dataset after the last load
private int previousTotalItemCount = 0;
// True if we are still waiting for the last set of data to load.
private boolean loading = true;
// Sets the starting page index
private int startingPageIndex = 0;

public EndlessScrollListener() {
}

public EndlessScrollListener(int visibleThreshold) {
    this.visibleThreshold = visibleThreshold;
}

public EndlessScrollListener(int visibleThreshold, int startPage) {
    this.visibleThreshold = visibleThreshold;
    this.startingPageIndex = startPage;
    this.currentPage = startPage;
}

// This happens many times a second during a scroll, so be wary of the code you place here.
// We are given a few useful parameters to help us work out if we need to load some more data,
// but first we check if we are waiting for the previous load to finish.
@Override
public void onScroll(AbsListView view,int firstVisibleItem,int visibleItemCount,int totalItemCount) 
    {
    // If the total item count is zero and the previous isn't, assume the
    // list is invalidated and should be reset back to initial state
    if (totalItemCount < previousTotalItemCount) {
        this.currentPage = this.startingPageIndex;
        this.previousTotalItemCount = totalItemCount;
        if (totalItemCount == 0) { this.loading = true; } 
    }
    // If it’s still loading, we check to see if the dataset count has
    // changed, if so we conclude it has finished loading and update the current page
    // number and total item count.
    if (loading && (totalItemCount > previousTotalItemCount)) {
        loading = false;
        previousTotalItemCount = totalItemCount;
        currentPage++;
    }

    // If it isn’t currently loading, we check to see if we have breached
    // the visibleThreshold and need to reload more data.
    // If we do need to reload some more data, we execute onLoadMore to fetch the data.
    if (!loading && (totalItemCount - visibleItemCount)<=(firstVisibleItem + visibleThreshold)) {
        onLoadMore(currentPage + 1, totalItemCount);
        loading = true;
    }
}

// Defines the process for actually loading more data based on page
public abstract void onLoadMore(int page, int totalItemsCount);

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
    // Don't take any action on changed
}
}

CustomAdapterSent.java

公共类CustomAdapterSent扩展BaseAdapter {

private ArrayList<Integer> mData = new ArrayList<Integer>();
private Context mContext;
private LayoutInflater inflater = null;

 private static final String TAG_NAME="name";
    private static final String TAG_PROFILE="profile_id";
    private static final String TAG_IMAGE="image";
    private static final String TAG_CAST="cast";
    private static final String TAG_AGE="age";
    private static final String TAG_LOCATION="location";

public CustomAdapterSent(ArrayList<Integer> mData, Context mContext) {
    this.mContext = mContext;
    this.mData = mData;
    inflater = (LayoutInflater) mContext
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

public void addAll(ArrayList<Integer> mmData) {
    this.mData.addAll(mmData);
    this.notifyDataSetChanged();
}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    return mData.size();
}

@Override
public Object getItem(int arg0) {
    // TODO Auto-generated method stub
    return mData.get(arg0);
}

@Override
public long getItemId(int arg0) {
    // TODO Auto-generated method stub
    return 0;
}

class ViewHolder {
    public TextView txtView;
    TextView txtproname;
}

@Override
public View getView(int postion, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    View view = convertView;
    ViewHolder holder;
    if (view == null) {
        view = inflater.inflate(R.layout.row_layout, null);
        holder = new ViewHolder();
        ///holder.propic = (ImageView) convertView.findViewById(R.id.propicsent);
      //  holder.txtproname = (TextView) convertView.findViewById(R.id.txtpronameintsent);
        //holder.txtproid = (TextView) convertView.findViewById(R.id.txtproidsent);
        //holder.txtprofilecast = (TextView) convertView.findViewById(R.id.txtprofilecastintsent);
        //holder.txtprofileage = (TextView) convertView.findViewById(R.id.txtprofileageintsent);
      //  holder.txtprofileplace = (TextView) convertView.findViewById(R.id.txtprofileplaceintsent);
        holder.txtView = (TextView) view.findViewById(R.id.no_intsent);
        view.setTag(holder);
    } else {
        holder = (ViewHolder) view.getTag();
    }
    Log.i("DATA", "mData.get(postion) :: " + mData.get(postion));
    mData.get(postion);
    // holder.txtproname.setText(listData.get(position).get(TAG_NAME));
    holder.txtView.setText("Index :: " + Integer.getInteger(TAG_NAME));
    return view;
}
}

XML档案:

   <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
 android:id="@+id/relativemainss"
android:background="@drawable/backg"
 >

 <ListView android:id="@android:id/list"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:dividerHeight="1dp">
 </ListView>
 <TextView 
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:layout_centerInParent="true"
    android:id="@+id/no_intsent"
    android:textColor="@android:color/black"
    android:background="@drawable/nomessaegborder" />

<Button 
      android:layout_height="wrap_content"
      android:layout_width="wrap_content"
      android:text="Load More"
      android:id="@+id/buttoloadmoreintsent"
     android:layout_below="@android:id/list" />


 </RelativeLayout>

问题答案:

要第一次仅显示10个项目ListView并滚动显示更多项目,请执行以下步骤:

步骤1: 创建一种chunkList方法,将ArrayList大小分成10个部分:

static <T> List<ArrayList<T>> chunkList(List<T> list, final int L) {
        List<ArrayList<T>> parts = new ArrayList<ArrayList<T>>();
        final int N = list.size();
        for (int i = 0; i < N; i += L) {
            parts.add(new ArrayList<T>(
                list.subList(i, Math.min(N, i + L)))
            );
        }
        return parts;
    }

第2步: 创建ArrayList一个计数器并显示当前零件:

    private boolean isLoadingMore=false;
    Handler mHandler = new Handler();
    List<ArrayList<HashMap<String,String>>> mainArrayList;
    private int count=0;

步骤3:onPostExecute突破result中ListView和显示数据:

protected void onPostExecute(ArrayList<HashMap<String,String>> result) {

              super.onPostExecute(result);
              // your code here...
               mainArrayList=chunkList(result,10);
               isLoadingMore=false;
               count=0;
               adapter = new CustomAdapterSent(Interestsent.this, 
                                            mainArrayList.get(count));
               setListAdapter(adapter);
        }

    }

步骤4: 在Adapter中创建addAll方法以将数据追加到当前数据源中:

public void addAll(ArrayList<HashMap<String,String>> moreData){
   this.listData.addAll(moreData);
   this.notifyDataSetChanged();
}

步骤5:onLoadMore ListView中加载更多数据:

mHandler = new Handler();
 listview.setOnScrollListener(new EndlessScrollListener() {
        @Override
        public void onLoadMore(int page, int totalItemsCount) {
                 if(count<mainArrayList.size()-1)
                  {
                     if(adapter !=null){
            count++;                       
            if(!isLoadingMore){
                             isLoadingMore=true;
                             mHandler.postDelayed(loadMoreRunnable,1000); 
                          } 
                      }
                  } 
        }
        });
    }

     Runnable loadMoreRunnable = new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
         if(count<mainArrayList.size())
                   {
                     if(adapter !=null){
                      count++;                       
                      adapter.addAll(mainArrayList.get(count));
                      mHandler.removeCallbacks(loadMoreRunnable);
                      isLoadingMore=false;
                      }
                  } 
        }
    };


 类似资料:
  • 我有一个android布局,它有一个,里面有很多元素。在的底部有一个,然后由适配器填充。 我遇到的问题是,android将从中排除,因为已经具有可滚动的功能。我希望与内容一样长,并且主滚动视图是可滚动的。 我怎样才能达到这种行为呢? 下面是我的主要布局: 然后以编程方式将组件添加到具有ID:的linearlayour中。下面是加载到LinearLayout中的一个视图。就是这个给我卷轴带来麻烦的。

  • 我一直在研究一个思想,在这个思想中,它保持自动滚动,而不需要用户交互,这一点在使用android API(例如,SmoothScrollTopositionFromTop)时是绝对可行的。 我需要提高流畅度,效率和控制速度

  • 我有带有三个片段的视图页面管理器,其中一个是带有滚动视图的框架布局: 如果我在按钮上滑动,它会工作。但是如果我在滚动视图上滑动,它就不起作用了,只有向上/向下滚动起作用。 编辑:我试图覆盖滚动视图的OnTouchEvent: 现在我可以禁用滚动,但滑动仍然不起作用,如果X点之间的差异超过40,我将事件传递给viewpager,但viewpager的onTouchListener没有收到此事件;

  • 我试图实现某种排序工具栏-但没有工具栏(而不是工具栏,它将是一个下拉元素,它本质上是一个RelativeLayout,其正下方有LinearLayout(下拉列表中的扩展项目),一旦按下下拉菜单,它就会在整个布局上悬停。 我考虑过实现折叠工具栏并将下拉列表放入工具栏中,但这可能不是一个好主意,因为下拉列表不是像图像视图这样的静态组件。我还在我的应用程序中使用了ActionBar,因此迁移到工具栏很

  • 当发生滚动时,我试图将< code>ListView项目动画化。更具体地说,我正试图模仿iOS 7上iMessage应用程序的滚动动画。我在网上找到一个类似的例子: 为了澄清,我试图在用户滚动时实现对项目的“流体”移动效果,而不是在添加新项目时实现动画。我试图修改我的中的视图,并且我已经研究了源代码,看看我是否可以以某种方式在某个地方附加一个,该器可以调整发送到子视图的绘制坐标(如果这是的设计方式

  • 我有一个列表视图,其中每个项目都显示一个月历。在每个项目中,我都有一个网格视图来显示日期。因此,通过滚动列表项,我可以看到日历月正在发生变化。但是列表视图的滚动并不流畅。通过搜索到目前为止我得到的解决方案,网格视图渲染中有5*7=35个项目,这使得滚动变慢。所以,我通过只返回文本视图而不是我的布局来更改网格适配器的getItem()。 我还使用AsyncTask加载数据,然后将数据馈送到网格适配器