RecyclerView.Adapter的上下文

时间:2016-10-18 06:59:09

标签: android android-adapter android-context

我想在适配器中添加ProgressDialog。 AFAIK,.this表示活动,getActivity.getApplicationContext()表示片段。适配器怎么样?有可能吗?

当我使用Unable to add window -- token null is not valid; is your activity running?时,我收到了错误mContext.getApplicationContext()

编辑:

在片段中,我通过

显示卡片
allGroupsView = (RecyclerView) rootView.findViewById(R.id.allGroupsView);
adapterGroup = new AdapterGroup(getActivity().getApplicationContext(), results);
allGroupsView.setAdapter(adapterGroup);
allGroupsView.setLayoutManager(new LinearLayoutManager(getActivity().getApplicationContext()));

在班级AdapterGroup

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

private Context mContext;
private LayoutInflater inflater;
List<DataGroup> data= Collections.emptyList();
DataGroup current;

public AdapterGroup(Context context, List<DataGroup> results) {
    this.mContext = context;
    inflater = LayoutInflater.from(mContext);
    this.data = results;
}

// Inflate the layout when viewholder created
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = inflater.inflate(R.layout.card_view_row, parent, false);
    final MyHolder holder = new MyHolder(view);

    view.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d("debug", String.valueOf(holder.getAdapterPosition()));
            getDetails(Config.GET_GROUP_DETAILS_URL, data.get(holder.getAdapterPosition()).groupName, data.get(holder.getAdapterPosition()).description);
        }
    });

    return holder;
}

private void getDetails(String url, String groupName, String description) {

    groupName = groupName.replace(" ", "%20");
    description = description.replace(" ", "%20");

    final String finalGroupName = groupName;
    final String finalDescription = description;

    class GetDetails extends AsyncTask<String, Void, String> {
        ProgressDialog loading;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            loading = ProgressDialog.show(mContext.getApplicationContext(), null, "Please wait", true, true);
            loading.setCancelable(false);
        } // more code down from here

6 个答案:

答案 0 :(得分:4)

我见过很多代码,人们在适配器中继续引用Context。但是在RecyclerView.Adapter中,可以从ViewHolder访问 itemView (您已从 onCreateViewHolder 中充气的视图)。在大多数情况下,您应该正在处理viewHolder。因此,请使用viewholder.itemView.getContext();.您甚至可以在viewholder getContext()中公开一个方法。

public Context getContext() {return itemView.getContext();}

答案 1 :(得分:2)

首先,上下文的类型之间存在一些差异。 参考:https://possiblemobile.com/2013/06/context/

示例:

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
     View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
     return new ViewHolder(v);
} 

@Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
    Context context = viewHolder.anyView.getContext();
}

答案 2 :(得分:1)

创建自定义Adapter并添加Constructor,以便Context可以传递。

public class CustomAdapter extends ArrayAdapter<String> {

    private Context context;
    private List<String> stringList = null;

    public CustomAdapter(Context context, int resource, List<String> objects) {
        super(context, resource, objects);
        this.context = context;
        this.stringList = objects;
    }
}

使用此&#39;上下文&#39;变量以根据您的要求显示ProgressDialog

答案 3 :(得分:1)

1.Pass适配器构造函数中的活动上下文。如果你的片段调用将它传递给getActivity()。

2.您也可以在onBindViewHolder中尝试itemView.getContext()。

我不确定使用#2方法的利弊,因为我总是使用#1。

答案 4 :(得分:1)

在片段中添加:

Context context;
#in onCreateView method:
context=getActivity();
allGroupsView = (RecyclerView) rootView.findViewById(R.id.allGroupsView);
adapterGroup = new AdapterGroup(context,results);
allGroupsView.setAdapter(adapterGroup);
allGroupsView.setLayoutManager(new LinearLayoutManager(getActivity()));

不要使用getActivity.getApplicationContext()或context.getApplicationContext()

loading = ProgressDialog.show(mContext, null, "Please wait", true, true);

答案 5 :(得分:0)

这对我来说非常适合尝试使用LinearLayoutManager

代替网格
Context mContext;

this.mContext = getActivity();


public void setAdapter() {
    adapter = new AllCategoriesAdapter(mContext, allCategoriesList);
    gridLayoutManager = new GridLayoutManager(getActivity(), 2, LinearLayoutManager.VERTICAL, false);
    ItemOffsetDecoration itemDecoration = new ItemOffsetDecoration(getActivity(), R.dimen.item_margin);
    gridRecyclerView.addItemDecoration(itemDecoration);
    gridRecyclerView.setHasFixedSize(true);
    gridRecyclerView.setLayoutManager(gridLayoutManager);
    gridRecyclerView.setItemAnimator(new DefaultItemAnimator());
    gridRecyclerView.setAdapter(adapter);
    adapter.notifyDataSetChanged();

   }



public class AllCategoriesAdapter extends RecyclerView.Adapter {


Context mContext;
List<AllCategories> allCategoriesList = new ArrayList<AllCategories>();

public AllCategoriesAdapter(Context mContext, List<AllCategories> allCategoriesList) {
    this.mContext = mContext;
    this.allCategoriesList = allCategoriesList;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(mContext).inflate(R.layout.allcategories_item, null);
    AllCategoriesHolder holder = new AllCategoriesHolder(itemView);
    holder.imageView = (ImageView) itemView.findViewById(R.id.imageView);
    holder.imageView_heart = (ImageView) itemView.findViewById(R.id.imageView_heart);
    holder.textViewName = (TextView) itemView.findViewById(R.id.textViewName);
    holder.textViewPlace = (TextView) itemView.findViewById(R.id.textViewPlace);
    holder.textViewPrice = (TextView) itemView.findViewById(R.id.textViewPrice);
    itemView.setTag(holder);

    itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            getDetails();
        }
    });

    return holder;
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    AllCategoriesHolder vh = (AllCategoriesHolder) holder;

    AllCategories allCategories = allCategoriesList.get(position);
    vh.textViewName.setText("" + allCategoriesList.get(position).getName());
    vh.textViewPlace.setText("" + allCategoriesList.get(position).getPlace());
    vh.textViewPrice.setText("" + allCategoriesList.get(position).getPrice());

    if (allCategories.isHeartLike()) {

    } else {

    }

    try {
        Glide.with(mContext)
                .load(allCategories.getImageUrl())
                .placeholder(PlaceHolderDrawableHelper.getBackgroundDrawable(position))
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .crossFade()
                .into(vh.imageView);
    } catch (NullPointerException ne) {
        ne.printStackTrace();
    } catch (IllegalArgumentException ia) {
        ia.printStackTrace();
    }

}

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

public void getDetails() {

    new GetDetails().execute();

}

class GetDetails extends AsyncTask<Void, Void, Void> {
    ProgressDialog loading;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        loading = ProgressDialog.show(mContext, "", "Please wait", true, true);
        loading.setCancelable(false);
    } // more code

    @Override
    protected Void doInBackground(Void... params) {
        return null;
    }


}

}