从recyclerview获取详细信息,并使用带有改造2网络库的cardview将结果显示在另一个片段中

时间:2016-11-10 09:55:19

标签: android json android-fragments android-recyclerview retrofit2

我在recyclerview中使用cardview列出改装请求的结果,接下来我想获得点击的cardview的详细信息,并在片段中显示cardview(json)的详细信息(简明扼要地说我使用片段列出并显示详细信息)

下面的代码是我的第一个片段,其中我使用改进2来获取json。这段代码工作正常,给出了输出json。

  public class AgentAssetsFragment extends Fragment implements View.OnClickListener {


    public TextView titleName, assetRate, assetBrand;
    public RecyclerView assetRecyclerView;
    List<AgentAsset> data;
    AgentAssetsAdapter agentAssetsAdapter;
    FrameLayout mLoadingFrame;
    public SharedPreferences pref;

    public AgentAssetsFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_agent_assets, container, false);
        assetRecyclerView = (RecyclerView) view.findViewById(R.id.agentAssetListRecyclerId);
        titleName = (TextView) view.findViewById(R.id.assetTitleId);
        assetRate = (TextView) view.findViewById(R.id.assetRateId);
        assetBrand = (TextView) view.findViewById(R.id.assetBrandId);
        mLoadingFrame = (FrameLayout) view.findViewById(R.id.agentLoadingFrame);
        initViews();
        mLoadingFrame.setVisibility(View.VISIBLE);

        return view;
    }

    private void initViews() {
        assetRecyclerView.setHasFixedSize(true);
        GridLayoutManager assetGridManager = new GridLayoutManager(getContext(), 2);
        assetRecyclerView.setLayoutManager(assetGridManager);
        assetRecyclerView.setAdapter(agentAssetsAdapter);
        getAssets();
    }

    private void getAssets() {

        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);

        OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
        httpClient.readTimeout(60, TimeUnit.SECONDS);
        httpClient.connectTimeout(60, TimeUnit.SECONDS);
        pref = this.getActivity().getSharedPreferences("LoginActivity", Context.MODE_PRIVATE);
        final String acToken = pref.getString("token", "DEFAULT");
        httpClient.addInterceptor(new Interceptor() {
            @Override
            public okhttp3.Response intercept(Chain chain) throws IOException {
                Request original = chain.request();

                Request request = original.newBuilder()
                        .header("Authorization", "Bearer " + acToken)
                        .method(original.method(), original.body())
                        .build();

                return chain.proceed(request);
            }
        });

        OkHttpClient client = httpClient.build();
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Constants.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build();

        final ApiInterface apiInterface = retrofit.create(ApiInterface.class);

        final AssetRequest assetRequest = new AssetRequest();

        final Call<List<AgentAsset>> call = apiInterface.getAssetListOfAgent();

        call.enqueue(new Callback<List<AgentAsset>>() {

            @Override
            public void onResponse(Call<List<AgentAsset>> call, Response<List<AgentAsset>> response) {
                int statusCode = response.code();

                if (statusCode == 200 && response.body() != null) {

                    List<AgentAsset> agentAssets = response.body();
                    data = agentAssets;

                    agentAssetsAdapter = new AgentAssetsAdapter(data);
                    id = agentAssetsAdapter.agentAssetId;
                    assetRecyclerView.setAdapter(agentAssetsAdapter);
                    Toast.makeText(getContext(), data.size() + " results", Toast.LENGTH_SHORT).show();

                } else if (statusCode == 406) {
                    Toast.makeText(getContext(), "Your token expired " + statusCode, Toast.LENGTH_LONG).show();

                } else if (response.body() == null) {

                    Toast.makeText(getContext(), "No results " + statusCode, Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(getContext(), "Network error, try again later " + statusCode, Toast.LENGTH_LONG).show();

                }
                mLoadingFrame.setVisibility(View.INVISIBLE);
            }

            @Override
            public void onFailure(Call<List<AgentAsset>> call, Throwable t) {
                mLoadingFrame.setVisibility(View.INVISIBLE);
                Toast.makeText(getContext(), "Error, Check your network ", Toast.LENGTH_LONG).show();
                Log.d("AgentAsset GET Failure", "onFailure: " + t.getMessage());
            }
        });
    }

    @Override
    public void onClick(View v) {

    }
}

这是我用于对RecyclerView进行充气的适配器类,其中我使用cardview来指示每个项目。我能够获得项目的位置点击,但当我尝试获取项目的ID时,它始终显示列表中最后一项的ID。我不知道为什么,从今天早上在stackoverflow中尝试了每个问题,没有找到我的查询结果。

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

    public List<AgentAsset> agentAssetLists;
    private static AgentAssetClickListener agentAssetClickListener;
    Integer agentAssetId;
    String href;

    public AgentAssetsAdapter(List<AgentAsset> agentAssetLists) {
        this.agentAssetLists = agentAssetLists;
    }

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

    public interface AgentAssetClickListener {
        void onItemClick(int position, View v);
    }

    @Override
    public AgentAssetsAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.agent_asset_card, viewGroup, false);
        return new ViewHolder(view);
    }


    @Override
    public void onBindViewHolder(AgentAssetsAdapter.ViewHolder holder, int position) {

        if (agentAssetLists != null) {

            holder.titleName.setText(agentAssetLists.get(position).getName());
            holder.assetBrand.setText(agentAssetLists.get(position).getBrand().getName());
            agentAssetId = agentAssetLists.get(position).getIdBrand();
            href = agentAssetLists.get(position).getLinks().getSelf().getHref();

            if (agentAssetLists.get(position).getRank() == -1) {
                holder.agentRank.setText("");
            } else {
                holder.agentRank.setText(String.valueOf(agentAssetLists.get(position).getRank()));
            }

            if (Objects.equals(agentAssetLists.get(position).getRate().getAvailable().toString(), "0")) {
                holder.assetRate.setText("nil");
            } else {
                holder.assetRate.setText(String.valueOf(agentAssetLists.get(position).getRate().getValue()));
            }

            if (Objects.equals(agentAssetLists.get(position).getBestRate().getAvailable().toString(), "0")) {
                holder.agentRate.setText("nil");
            } else {
                holder.agentRate.setText(String.valueOf(agentAssetLists.get(position).getBestRate().getValue()));
            }

        } else {

            holder.resultCount.setText("No Assets, Try Later");
        }

    }

    public void addItems(List<AgentAsset> asResponse, int index) {
        int cursize = agentAssetLists.size();
        agentAssetLists.addAll(index, asResponse);
        if (getItemCount() != 0) {
            notifyItemRangeInserted(index, (agentAssetLists.size() - cursize));
        } else {
            notifyDataSetChanged();
        }
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        TextView titleName, assetRate, assetBrand, agentRate, agentRank, resultCount;
        ImageView assetImage;

        public ViewHolder(View view) {
            super(view);

            resultCount = (TextView) view.findViewById(R.id.resultCountId);
            titleName = (TextView) view.findViewById(R.id.agentAssetTitleId);
            assetRate = (TextView) view.findViewById(R.id.assetRateId);
            assetBrand = (TextView) view.findViewById(R.id.agentAssetBrandId);
            agentRank = (TextView) view.findViewById(R.id.agentRankId);
            agentRate = (TextView) view.findViewById(R.id.agentAssetRateId);
            itemView.setOnClickListener(this);
            //img_android = (ImageView) view.findViewById(R.id.img_android);
        }

        @Override
        public void onClick(View v) {
            //Log.d("item clicked", "item clicked" + getAdapterPosition() );
            Toast.makeText(v.getContext(), "clicked aaa " + getAdapterPosition(), Toast.LENGTH_SHORT).show();

        }
    }

    public void setOnItemClickListener(AgentAssetClickListener agentAssetClickListener) {
        AgentAssetsAdapter.agentAssetClickListener = agentAssetClickListener;

    }

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

如何从项目中获取ID?以及如何将数据传递到下一个片段,该片段显示当前点击的cardview的完整详细信息?任何帮助表示赞赏 提前谢谢。

修改 我忘了附上我的json回复,这是它

 [
  {
    "id_asset": 1,
    "id_category": 1,
    "id_brand": 2,
    "name": "Samsung Galaxy 6",
    "status": 1,
    "updated_at": "Oct 3, 2016 10:24:28 AM",
    "rank": 1,
    "rate": {
      "available": 1,
      "id_asset_rate": 2,
      "id_asset": 1,
      "id_user": 10,
      "value": 5000,
      "loan_to_value": 50,
      "offered": 2500,
      "annual_rate": 3,
      "quantity": 5,
      "status": 1,
      "created_at": 1477200691,
      "updated_at": 1477200751
    },
    "best_rate": {
      "available": 1,
      "id_asset": 1,
      "value": 5000,
      "loan_to_value": 50,
      "offered": 2500,
      "annual_rate": 3,
      "quantity": 5,
      "rank": 1
    },
    "category": {
      "id_category": 1,
      "id_parent": 0,
      "name": "Mobile Phones",
      "image": "",
      "sort": 1,
      "status": 1,
      "created_at": null,
      "updated_at": null,
      "_links": {
        "self": {
          "href": "/v1/categories/1"
        }
      }
    },
    "brand": {
      "id_brand": 2,
      "name": "Samsung",
      "status": 1,
      "created_at": null,
      "updated_at": null
    },
    "_links": {
      "self": {
        "href": "/v1/assets/1"
      }
    }
  } ]

1 个答案:

答案 0 :(得分:1)

您在适配器中的每个onBind上覆盖您的ID:

这里你应该得到null,因为在将适配器设置为RecyclerView之前永远不会设置id:

@Override
public void onResponse(Call<List<AgentAsset>> call, Response<List<AgentAsset>> response) {
    //...
    if (statusCode == 200 && response.body() != null) {
        //...
        agentAssetsAdapter = new AgentAssetsAdapter(data);
        id = agentAssetsAdapter.agentAssetId; //<---
        //...
   }
//...
}

这里用资产ID的每次绑定迭代覆盖:

@Override
public void onBindViewHolder(AgentAssetsAdapter.ViewHolder holder, int position) {

    if (agentAssetLists != null) {    
        holder.titleName....        
        holder.assetBrand....
        //here you overwrite the id on every iteration.
        agentAssetId = agentAssetLists.get(position).getIdBrand();
        href =  ....
    }
}

结果是您获得了适配器中最新绑定资产项的ID。

这可能是您的解决方案:

调整界面:

public interface AgentAssetClickListener {
    void onItemClick(int position, AgentAsset item);
}

实施您的界面:

public class AgentAssetsFragment extends Fragment implements AgentAssetsAdapter.AgentAssetClickListener {


    public TextView titleName, assetRate, assetBrand;
    public RecyclerView assetRecyclerView;
    List<AgentAsset> data;
    AgentAssetsAdapter agentAssetsAdapter;
    FrameLayout mLoadingFrame;
    public SharedPreferences pref;

    public AgentAssetsFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        //...
        initViews();
        mLoadingFrame.setVisibility(View.VISIBLE);

        return view;
    }

    private void initViews() {
        assetRecyclerView.setHasFixedSize(true);
        GridLayoutManager assetGridManager = new GridLayoutManager(getContext(), 2);
        assetRecyclerView.setLayoutManager(assetGridManager);
        getAssets();
    }

    private void getAssets() {

        //...

        call.enqueue(new Callback<List<AgentAsset>>() {

            @Override
            public void onResponse(Call<List<AgentAsset>> call, Response<List<AgentAsset>> response) {
                int statusCode = response.code();

                if (statusCode == 200 && response.body() != null) {

                    List<AgentAsset> agentAssets = response.body();
                    data = agentAssets;

                    agentAssetsAdapter = new AgentAssetsAdapter(data);
                    agentAssetsAdapter.setOnItemClickListener(AgentAssetsFragment.this);
                    assetRecyclerView.setAdapter(agentAssetsAdapter);
                    //id = agentAssetsAdapter.agentAssetId; //gon't know for what you use this...

                    Toast.makeText(getContext(), data.size() + " results", Toast.LENGTH_SHORT).show();

                } else if //...

                mLoadingFrame.setVisibility(View.INVISIBLE);
            }

            @Override
            public void onFailure(Call<List<AgentAsset>> call, Throwable t) {
                //...
            }
        });
    }

    @Override
    public void onItemClick(int position, AgentAsset item) {
        //item.getLinks().getSelf().getHref();
        //item.getAssetId();
        //Log.d("item clicked", "item clicked" + getAdapterPosition() );
        Toast.makeText(getContext(), "Asset["+position+"] clicked: " + item, Toast.LENGTH_SHORT).show();
    }
}

在Recycler适配器中调整绑定方法;

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

    //why static?
    //private static AgentAssetClickListener agentAssetClickListener;
    //Integer agentAssetId;
    //String href;

    public List<AgentAsset> agentAssetLists;        
    private AgentAssetClickListener agentAssetClickListener;



    public AgentAssetsAdapter(List<AgentAsset> agentAssetLists) {
        this.agentAssetLists = agentAssetLists;
    }

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

    public interface AgentAssetClickListener {
        void onItemClick(int position, View v);
    }

    @Override
    public AgentAssetsAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.agent_asset_card, viewGroup, false);
        return new ViewHolder(view);
    }


    @Override
    public void onBindViewHolder(AgentAssetsAdapter.ViewHolder holder, int position) {

        if (agentAssetLists != null) {
            AgentAsset agentA = agentAssetLists.get(position);
            holder.titleName.setText(agentA.getName());
            holder.assetBrand.setText(agentA.getBrand().getName());

            //global values were overwritten by every new agentA, what is the need for this?
            //href = agentA.getLinks().getSelf().getHref();
            //agentAssetId = agentA.getIdBrand();

            //set an onlick listener to the itemView and call the agentAssetClickListener.onItemClick();
            holder.itemView.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View v) {
                    if(agentAssetClickListener != null){
                        agentAssetClickListener.onItemClick(holder.getAdapterPosition(), agentA);
                    }
                }
            });

            if (agentA.getRank() == -1) {
                holder.agentRank.setText("");
            } else {
                holder.agentRank.setText(String.valueOf(agentA.getRank()));
            }

            if (Objects.equals(agentA.getRate().getAvailable().toString(), "0")) {
                holder.assetRate.setText("nil");
            } else {
                holder.assetRate.setText(String.valueOf(agentA.getRate().getValue()));
            }

            if (Objects.equals(agentA.getBestRate().getAvailable().toString(), "0")) {
                holder.agentRate.setText("nil");
            } else {
                holder.agentRate.setText(String.valueOf(agentA.getBestRate().getValue()));
            }

        } else {

            holder.resultCount.setText("No Assets, Try Later");
        }

    }

    public void addItems(List<AgentAsset> asResponse, int index) {
        //...
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        TextView titleName, assetRate, assetBrand, agentRate, agentRank, resultCount;
        ImageView assetImage;

        public ViewHolder(View view) {
            super(view);

            resultCount = (TextView) view.findViewById(R.id.resultCountId);
            titleName = (TextView) view.findViewById(R.id.agentAssetTitleId);
            assetRate = (TextView) view.findViewById(R.id.assetRateId);
            assetBrand = (TextView) view.findViewById(R.id.agentAssetBrandId);
            agentRank = (TextView) view.findViewById(R.id.agentRankId);
            agentRate = (TextView) view.findViewById(R.id.agentAssetRateId);

            //no need anymore
            //itemView.setOnClickListener(this);

            //img_android = (ImageView) view.findViewById(R.id.img_android);
        }
    }

    public void setOnItemClickListener(AgentAssetClickListener agentAssetClickListener) {
        this.agentAssetClickListener = agentAssetClickListener;

    }
}

AgentAssetClickListener 的侦听器通过 onItemClick(int,AgentAsset)获取项目,以便您可以通过 AgentAsset <的getter方法获取项目品牌ID / em> class。 如果id仍然相同,那么您的数据结构创建就会出现问题。

编辑:扩展答案以便更好地理解。