2016-10-18 3 views
0

Я хочу добавить ProgressDialog в адаптер. AFAIK, .this для деятельности, и getActivity.getApplicationContext() для фрагмента. Что относительно адаптера? Является ли это возможным?Контекст для RecyclerView.Adapter

У меня ошибка Unable to add window -- token null is not valid; is your activity running?, когда я использую mContext.getApplicationContext().

EDIT:

Во фрагменте, я показываю карты,

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 
+1

создать 'constructor' вашего адаптера и передать контекст из' деятельности/fragment' –

+0

'Activity' уже является' context'. Зачем вам нужен getApplicationContext? Тот же вопрос для 'mContext.getApplicationContext()' ... –

+0

@ cricket_007 класс не является 'Activity', поэтому я решил, что, возможно, я могу использовать тот же путь с фрагментом. Исключение оказалось невозможным:/ – August

ответ

0

Создание пользовательских 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; 
    } 
} 

Используйте этот «контекст» переменной, чтобы показать ProgressDialog согласно вашему требованию.

+1

Вопрос о RecyclerView.Adapter. Кроме того, сохранение переменной-члена 'context' в' ArrayAdapter' является избыточным. –

+0

Вы также можете использовать это для адаптера RecyclerView. – vidulaJ

+0

Несомненно. Я думаю, что вопрос уже делает это, однако, поскольку «mContext» представляется переменной в адаптере, а «mContext.getApplicationContext» выбрасывает исключение –

1

1.Пазовый контекст активности в конструкторе для адаптера. если ваш вызов из фрагмента передается как getActivity().

2. Вы также можете попробовать itemView.getContext() в onBindViewHolder.

Я не уверен в преимуществах и недостатках использования метода # 2, потому что я всегда использую # 1.

+0

вы можете взглянуть на мои новые коды? – August

+0

Увидев обновленный код, я чувствую, что лучше передать контекст в конструкторе. – WritingForAnroid

1

Во-первых, существуют некоторые различия между типом Контексты. Ссылка: 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(); 
} 
0

В фрагмент добавить:

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); 
+0

'Попытка вызвать виртуальный метод 'java.lang.Object android.content.Context.getSystemService (java.lang.String)' в ссылке нулевого объекта' – August

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; 
    } 


} 

} 
1

Я видел много кода, в котором люди ссылаются на контекст в адаптере. Но в RecyclerView.Adapter, itemView (вид, который вы уже надули от onCreateViewHolder) доступен из вашего ViewHolder. По большей части, вы должны иметь дело с viewHolder в любом случае. Итак, используйте viewholder.itemView.getContext() ;. Вы можете даже разоблачить метод в вашем телезрителе getContext().

public Context getContext() {return itemView.getContext();} 
Смежные вопросы