RecycleView适配器中的列表有时出现,其他时间失败

时间:2018-05-28 21:21:33

标签: android android-recyclerview okhttp butterknife android-mvp

在开发Android应用时,我遇到了一个相当棘手的问题。该应用程序是加密货币RESTFul服务的客户端。它以最简单的形式获取一系列虚拟硬币的信息,并将它们显示在列表中,使用RecycleView组件显示。

问题是有时会显示硬币列表,如下所示 enter image description here

其他时间,但它没有这样做,甚至我的调试行告诉我数据已被提取。在后一种情况下,当我拖放屏幕时,列表会显示出来(哦,是的,我将SwipeRefreshLayout添加到我的Fragment类并实现了必需品)。

enter image description here

该应用程序是使用MVP模式开发的,相关代码如下:

交互器类充当后端服务,通过RESTFul服务获取JSON数据,使用OKHttp lib和RxJava:

@Override
public Observable<List<Coin>> fetchCoins(){
    //TODO
    return Observable.fromCallable(this::getCoinList);
}

private List<Coin> getCoinList() throws IOException, JSONException {
    Request request = RequestGenerator.get(Api.BIT_COINS_LIST);
    String response = requestHandler.request(request);
    List<Coin> coinList = CoinListingParser.parse(response);
    return coinList;
}

presenter类桥接从交互器和视图类获取的数据:

@Override
public void fetchCoins() {
    showLoading();
    fetchSubscription = coinListingInteractor.fetchCoins().subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(this::onCoinFetchSuccess, this::onCoinFetchFailed);
}


    private void onCoinFetchSuccess(List<Coin> list)
{
    Log.d("CoinListing", "fetch succeeded");
    if (isViewAttached())
    {
        coinListView.showCoins(list);
        coinListView.loaded();
    }
}

Fragment类实现了coinListView类,并实现了我们在presenter类中看到的showCoins方法,以便数据和GUI组件绑定 - ButterKnife用于简洁明了的代码:

public class CoinListingFragment extends Fragment implements CoinListingView,SwipeRefreshLayout.OnRefreshListener {

    @Inject
    CoinListingPresenter coinPresenter;

    @Bind(R.id.coin_listing)
    RecyclerView coinListRecycleView;

    @Bind(R.id.swipe_container)
    SwipeRefreshLayout mSwipeRefreshLayout;

    private RecyclerView.Adapter adapter;
    private List<Coin> coinList = new ArrayList<>(20);

    @Override
    public void showCoins(List<Coin> list) {
        this.coinList.clear();
        this.coinList.addAll(list);
        coinListRecycleView.setVisibility(View.VISIBLE);
        adapter.notifyDataSetChanged();
    }

    @Override
    public void onResume(){
        super.onResume();
        getActivity().runOnUiThread(()-> {coinPresenter.fetchCoins();});
    }
}

随附的RecycleView.Adapter类如下所示:

public class CoinListingAdapter extends RecyclerView.Adapter<CoinListingAdapter.ViewHolder>{

    private List<Coin> coinList;
    private Context context;
    private CoinListingView view;
    public CoinListingAdapter(List<Coin> list, CoinListingView coinView)
    {
        this.coinList = list;
        view = coinView;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        context = parent.getContext();
        View rootView = LayoutInflater.from(context).inflate(R.layout.fragment_coin_list_grid, parent, false);

        return new ViewHolder(rootView);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.itemView.setOnClickListener(holder);
        holder.coin = coinList.get(position);
        holder.name.setText(holder.coin.getFullName()+"("+holder.coin.getName()+")");
        Picasso.with(context).load(holder.coin.getImageUrl()).into(holder.img);
        holder.price.setText(holder.coin.getPrice());
    }

    @Override
    public int getItemCount() {
        return coinList.size();
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
    {
        @Bind(R.id.coin_name)
        public TextView name;
        @Bind(R.id.image_thumb)
        public ImageView img;
        @Bind(R.id.coin_price)
        public TextView price;

        public Coin coin;

        public ViewHolder(View root)
        {
            super(root);
            ButterKnife.bind(this, root);

        }
    }
}

1 个答案:

答案 0 :(得分:0)

我问的是错误的问题。问题出在RESTFul webserivce而不是客户端。服务提供商限制对其服务的访问。如果请求过于频繁,则会抛出“超出速率限制”错误,并且不会获取任何数据。