Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在回收视图中列出';s适配器在某个时间出现,其他时间出现故障_Android_Android Recyclerview_Okhttp_Butterknife_Android Mvp - Fatal编程技术网

Android 在回收视图中列出';s适配器在某个时间出现,其他时间出现故障

Android 在回收视图中列出';s适配器在某个时间出现,其他时间出现故障,android,android-recyclerview,okhttp,butterknife,android-mvp,Android,Android Recyclerview,Okhttp,Butterknife,Android Mvp,在开发android应用程序时,我遇到了一个相当回避的问题。该应用程序是加密货币RESTFul服务的客户端。最简单的形式是,它获取一系列虚拟硬币的信息,并将它们显示在一个列表中,使用RecycleView组件显示 问题在于,硬币清单有时会按预期显示,见下文 另一次,尽管它没有这样做,甚至我的调试行都告诉我数据已经被提取了。在后一种情况下,当我拖放屏幕时,列表将显示出来(哦,是的,我将SwipeRefreshLayout添加到了我的Fragment类中,并实现了必要的功能) 应用程序采用MVP

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

问题在于,硬币清单有时会按预期显示,见下文

另一次,尽管它没有这样做,甚至我的调试行都告诉我数据已经被提取了。在后一种情况下,当我拖放屏幕时,列表将显示出来(哦,是的,我将SwipeRefreshLayout添加到了我的Fragment类中,并实现了必要的功能)

应用程序采用MVP模式开发,相关代码如下:

interactor类充当后端服务,通过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;
}
@覆盖
公众可观察硬币(){
//待办事项
返回Observable.fromCallable(this::getCoinList);
}
私有列表getCoinList()抛出IOException、JSONException{
请求=RequestGenerator.get(Api.BIT\u\u列表);
字符串响应=requestHandler.request(请求);
List coinList=CoinListingParser.parse(响应);
返回列表;
}
presenter类将从interactor和view类获取的数据连接起来:

@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();
    }
}
@覆盖
公众硬币(){
showLoading();
fetchSubscription=coinListingInteractor.fetchCoins().subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::oncoInfectchSuccess,this::oncoInfectchFailed);
}
私有无效OnCountchSuccess(列表)
{
Log.d(“CoinListing”、“fetch successed”);
如果(isViewAttached())
{
coinListView.showCoins(列表);
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();});
    }
}
公共类CoinListingFragment扩展片段实现CoinListingView、SwipeRefreshLayout.OnRefreshListener{
@注入
CoinListingPresenter coinPresenter;
@绑定(R.id.coin_列表)
RecyclerView硬币列表Recyclereview;
@绑定(R.id.swipe\u容器)
SwipeRefreshLayout mSwipeRefreshLayout;
专用循环视图适配器;
私有列表coinList=新的ArrayList(20);
@凌驾
公开作废展示币(列表){
this.coinList.clear();
this.coinList.addAll(列表);
coinListRecycleView.setVisibility(View.VISIBLE);
adapter.notifyDataSetChanged();
}
@凌驾
恢复时公开作废(){
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);

        }
    }
}
公共类CoinListingAdapter扩展了RecyclerView.Adapter{
私人名单;
私人语境;
私有CoinListingView;
公共CoinListingAdapter(列表列表,CoinListingView coinView)
{
this.coinList=列表;
视图=coinView;
}
@凌驾
public ViewHolder onCreateViewHolder(视图组父级,int-viewType){
context=parent.getContext();
View rootView=LayoutInflater.from(context).充气(R.layout.fragment\u coin\u list\u grid,parent,false);
返回新的ViewHolder(rootView);
}
@凌驾
公共无效onBindViewHolder(ViewHolder,int位置){
holder.itemView.setOnClickListener(holder);
holder.coin=coinList.get(位置);
holder.name.setText(holder.coin.getFullName()+”(“+holder.coin.getName()+”);
毕加索.with(context).load(holder.coin.getImageUrl())到(holder.img);
holder.price.setText(holder.coin.getPrice());
}
@凌驾
public int getItemCount(){
返回coinList.size();
}
@凌驾
附加ToRecyclerView(RecyclerView RecyclerView)上的公共无效{
super.onAttachedToRecyclerView(recyclerView);
}
公共类ViewHolder扩展了RecyclerView.ViewHolder实现了View.OnClickListener
{
@绑定(R.id.coin\u名称)
公共文本视图名称;
@绑定(R.id.image\u拇指)
公共图像视图img;
@绑定(R.id.coin\u价格)
公共文本视图价格;
公众硬币;
公共视图持有者(视图根)
{
超级(根);
把(这个,根)绑起来;
}
}
}

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

我正在研究的一些问题可能是问题,但看不到。我看不到您在
notifyDataSetChanged()
之外与适配器交互的位置。您正在添加并清除
列表
,但不是适配器。我不知道
coinListView.loaded()
做什么。我想知道1:您是否重新验证了
coinList
,2:是否有种族清除和更新RecyclerView。感谢您的深入了解。将列表部分移动到适配器是一个很好的建议。Loaded()只是在加载完成后停止等待图标的旋转。然而,我发现我对错了树吠叫。见下面我的答案。