0

我正在尝试更新我的列表视图以制作“无尽滚动”。发生的情况是前 40 个结果加载正常,当我到达滚动底部时,接下来的 40 个结果将替换前 40 个......

我想要的是将第二组 40 个结果添加到前 40 个结果中,这样我就有了一个无穷无尽的列表,并且能够滚动回列表的开头。

我在下面发布我的代码。谢谢!

public class SearchResults extends Activity implements BannerAdListener, OnScrollListener{

    private LinearLayout bottomNav;
    private ListView ringtoneList;
    private int start = 0, num = 40, curPage = 1;
    private Handler handler = new Handler();
    private ProgressDialog progressDialog = null;
    private ArrayList<Ringtone> ringtones;
    private MoPubView moPubView;  
    private String searchString;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Bundle extras = getIntent().getExtras();
        if (extras == null) {
            // no search string defined
            finish();
        } else {
            searchString = extras.getString("search_string");
        }

        setContentView(R.layout.search_results);    

        ringtoneList = (ListView)findViewById(R.id.ringtone_list);
        ringtoneList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> av, View view, int position, long id) {
                Intent i = new Intent(SearchResults.this, RingtoneView.class);
                i.putExtra("ringtone", ringtones.get(position));
                startActivity(i);
            }
        });

        performSearch();

        moPubView = (MoPubView) findViewById(R.id.adview);
        moPubView.setAdUnitId(Utils.MoPubBannerId);
        moPubView.loadAd();
        moPubView.setBannerAdListener(this);

        ringtoneList.setOnScrollListener(this);

    }

    public void onScroll(AbsListView view, int firstVisible, final int visibleCount, int totalCount) {

            Log.i("List", "firstVisible="+firstVisible+" visibleCount="+visibleCount+" totalCount="+totalCount);

            boolean loadMore = firstVisible + visibleCount >= totalCount;

            if(loadMore) {

                Log.i("List", "Loading More Results");                

                curPage++;
                start = num * (curPage-1);

                new Thread() {

                    public void run() {

                        ringtones = Utils.search(start, num, searchString);

                        if (ringtones != null && ringtones.size() > 0) {

                            handler.post(new Runnable() {
                                public void run() {
                                    ringtoneList.setAdapter(new RingtoneRowAdapter(SearchResults.this, ringtones));
                                }
                            });

                        } else {

                            handler.post(new Runnable() {
                                public void run() {
                                    new AlertDialog.Builder(SearchResults.this)
                                    .setTitle(getResources().getString(R.string.context_info)).setMessage(getResources().getString(R.string.context_noresult))
                                    .setPositiveButton(getResources().getString(R.string.context_ok), null).show();
                                }
                            });

                        }

                    }
                }

                .start();
         }
    }

    public void onScrollStateChanged(AbsListView v, int s) { } 

    private void performSearch() {
        progressDialog = ProgressDialog.show(SearchResults.this, getResources().getString(R.string.loading_message), getResources().getString(R.string.loading_search), true); 
        new Thread() {
            public void run() {
                ringtones = Utils.search(start, num, searchString);
                if (ringtones != null && ringtones.size() > 0) {
                    updateList();
                } else {
                    handler.post(new Runnable() {
                        public void run() {
                            new AlertDialog.Builder(SearchResults.this)
                            .setTitle(getResources().getString(R.string.context_info)).setMessage(getResources().getString(R.string.context_noresult))
                            .setPositiveButton(getResources().getString(R.string.context_ok), null).show();
                            ringtoneList.setVisibility(View.INVISIBLE);
                            bottomNav.setVisibility(View.INVISIBLE);
                        }
                    });
                }
                progressDialog.dismiss();
            }
        }.start();
    }

    private void updateList() {
        handler.post(new Runnable() {
            public void run() {
                //Log.d("search", "ringtones.size() " + ringtones.size());
                ringtoneList.setVisibility(View.VISIBLE);
                ringtoneList.setAdapter(new RingtoneRowAdapter(SearchResults.this, ringtones));
            }
        });
    }

}

请帮忙!谢谢!

4

2 回答 2

0

虽然我不能 100% 确定,但我认为您的问题与您设置的新适配器有关,该适配器只有加载中的铃声部分。它可能与这个片段有关:

ringtones = Utils.search(start, num, searchString);

if (ringtones != null && ringtones.size() > 0) {

    handler.post(new Runnable() {
        public void run() {
            ringtoneList.setAdapter(new RingtoneRowAdapter(SearchResults.this, ringtones));
        }
    });

}

而不是放置一个全新的铃声阵列,你应该添加到你已经拥有的铃声上。您的ringtones变量已经是一个实例变量,所以我确定您是否更改了这一行:

ringtones = Utils.search(start, num, searchString);

到以下:

ringtones.addAll(Utils.search(start, num, searchString));

它可能会解决您的问题。

于 2013-10-31T19:50:11.893 回答
0

您的代码有点混乱,但您的 updateList 方法正在创建一个新的 RingtoneRowAdapter。您应该将项目添加到列表并调用

mRingtoneRowAdapter.notifyDatasetChanged();

这将告诉适配器获取新视图(如果需要)以及在适配器级别发生的许多内部事情。所以有点:

   private void updateList() {
         handler.post(new Runnable() {
            public void run() {
                if ( mAdapter == null ) { 
                   mAdapter = new RingtoneRowAdapter(SearchResults.this, ringtones);
                   ringtoneList.setAdapter(mAdapter);
                } else {
                   mAdapter.notifyDataSetChanged();
                }
                ringtoneList.setVisibility(View.VISIBLE);
            }
        });
    }

当然,正如已经建议的那样,不要一直初始化你的铃声数组。只需向其中添加数据。

您不需要(大多数时候)隐藏列表,您可以在布局中添加任何具有以下 ID 的视图(包括完整布局!):

android:id="@android:id/empty"

如果您的 ListView 的 id 为 android:id="@id/android:list",并且您在 ListFragment 或 ListActivity 中,那么当列表为空时,将显示“空”布局(可以是如果您不想看到它,请使用虚拟视图)。

只是建议:)

更新:对于您的 null,我看到逻辑有点奇怪,因为我们不知道您的应用程序的要求(即如果没有结果该怎么办,如果结果无效怎么办,等等。 ) 我假设您只是想确保它正常工作并稍后处理。

因此,考虑到这一点,我看到了两个问题。

  1. 我假设您的 Utils.search 方法可以返回 null,因为您正在检查它。对我来说这感觉很奇怪,我宁愿返回一个空数组,表示搜索没有产生结果;撇开那一点点不谈,您没有检查(或者我们不知道,因为我们没有看到您的搜索方法的来源),如果 searchString 为空。
  2. 您没有提供堆栈跟踪,因此我们无法判断 null 发生在哪里(在搜索内部还是?)

一个快速的解决方案是在搜索之前检查 null ......我个人会在搜索功能中执行此操作。

就像是:

public ArrayList<Ringtone> search(final int start, final int num, final String searchString) {

   if ( searchString == null ) {
       //DECIDE WHAT YOU WANT TO DO, EITHER:
       return null;
       // OR YOU CAN RETURN AN EMPTY ARRAY
       return new ArrayList<Ringtone>(); 
    }
   // You should check for these (change according to your rules)
   if (start < 0 ) {
      start = 0; // protect yourself from bad data.
   }
   if ( num < 0 ) {
       num = 0; 
   } 
    /// THE REST OF YOUR search FUNCTION

   return <your array>
}

现在另一件事是您可能希望搜索返回增量结果(因此您可以将它们添加到您的数组中(而不是每次都返回一个新数组)。为此,正如已经建议的那样,使用 addAll 技巧,但是,不要'T return null,返回一个新的空数组,所以如果没有什么要添加的,也没有什么坏处。

于 2013-10-31T19:50:18.993 回答