Не виден метод getFragmentManager

199
27 июля 2018, 22:30

Имеется RecyclerView. Необходимо по нажатию на элемент перейти во фрагмент. Но метод getFragmentManager не виден.

public class CategoriesAdapter extends RecyclerView.Adapter<CategoriesAdapter.ViewHolder> {
    private List<Category> categories;
    private Context ctx;
    public CategoriesAdapter(List<Category> categories, Context ctx) {
        this.categories = categories;
        this.ctx = ctx;
    }
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.list_categories, parent, false);
        return new ViewHolder(v);
    }
    @Override
    public void onBindViewHolder(CategoriesAdapter.ViewHolder holder, int position) {
        final Category category = categories.get(position);
        holder.textViewCategoryName.setText(category.getName());
    }
    @Override
    public int getItemCount() {
        return categories.size();
    }


    public class ViewHolder extends RecyclerView.ViewHolder{
        public TextView textViewCategoryName;
        public ViewHolder(final View itemView) {
            super(itemView);
            textViewCategoryName = (TextView) itemView.findViewById(R.id.textViewCategoryName);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Fragment fragment = null;
                    Category category =(Category) categories.get(getAdapterPosition());
                    switch (category.getName()){
                        case "Смартфон":
                            fragment = new SearchSmartphoneFragment();
                            break;
                        case "Планшет":
                            break;
                    }
                    if (fragment != null) {
                        FragmentManager fragmentManager = getFragmentManager();
                        FragmentTransaction ft = fragmentManager.beginTransaction();
                        ft.replace(R.id.content_frame,fragment);
                        ft.commit();
                    }

                }
            });
        }
    }
}
Answer 1

Можете сделать так:

если ваша Activity наследует Activity:

FragmentManager fragmentManager = ((Activity) itemView.getContext()).getFragmentManager();

если ваша Activity наследует AppCompatActivity:

FragmentManager fragmentManager = ((AppCompatActivity) itemView.getContext()).getSupportFragmentManager();

Код добавьте в конструктор вашего ViewHolder(а).

Объяснение: Метод отсутствует потому что у вас используются support библиотеки, а у них нужно вызывать .getSupportFragmentManager() а этого метода нет в классе Activity, он есть только у класса FragmentActivity, который в свою очередь наследует AppCompatActivity.

p.s. я бы может через delegat(e) это еще сделал, а сам делаю через Cicerone, используя ApplcationContext (жду конечно же комментарий).

Answer 2

Это потому, что вы вызваете его в адаптере. FragmentManager может быть вызван только в активити или фрагменте. Передайте его как параметр в адаптер и используйте. Замечание по коду. Метод котоырй вы вызываете по клику следует передавать в адаптер в виде интерфейса с помощью callback. Посмотрие приведенный пример:

Адаптер + Интерфейс

interface ClickToProfile {
        fun openProfile(user: User)
}   

class PeopleAdapter(context: Context, private var items: MutableList<User>, private var clickToProfile: ClickToProfile) :
            RecyclerView.Adapter<PeopleViewHolderItem>() {
        private val inflater: LayoutInflater = LayoutInflater.from(context)
        override fun onBindViewHolder(viewHolder: PeopleViewHolderItem, position: Int) {
            viewHolder.bindTo(items[position])
        }
        override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): PeopleViewHolderItem {
            return PeopleViewHolderItem.create(inflater, viewGroup, clickToProfile)
        }
        override fun getItemCount(): Int {
            return items.size
        }
    }

Как использовать:

private fun setupRecyclerView(users: ArrayList<User>) {
    adapter = PeopleAdapter(context!!, users, object : ClickToProfile {
        override fun openProfile(user: User) {
            adapter.notifyDataSetChanged()
            listener?.replaceFragment(ProfileFragment.newInstance(user), true)
        }
    })
    recyclerView.adapter = adapter
}

и ViewHolder:

class PeopleViewHolderItem private constructor(view: View,
                                               private val clickToProfile: ClickToProfile) : RecyclerView.ViewHolder(view) {
    private val itemHuman = view.itemPeople
    @SuppressLint("SetTextI18n")
    fun bindTo(user: User) {   
        // listener
        itemHuman.setOnClickListener { selectAndOpen(user) }
        itemHuman.moreBtn.setOnClickListener { selectAndOpen(user) }
    }
    private fun selectAndOpen(user: User) {
        clickToProfile.openProfile(user)
        selectedPosition = layoutPosition
    }
    companion object {
        var selectedPosition = -1
        fun create(inflater: LayoutInflater,
                   parent: ViewGroup, clickToProfile: ClickToProfile): PeopleViewHolderItem {
            return PeopleViewHolderItem(inflater.inflate(R.layout.item_people, parent, false), clickToProfile)
        }
    }
}

Код приведен на Kotlin, но идея верна и для java

READ ALSO
взаимное расположение img в css

взаимное расположение img в css

Задача: расставить изображения так, как показано в рисунке во вложении ( два друг под другом, а третье - справа)

186
Не выводится alert

Не выводится alert

Вот такой код:

164
прочитать json файл в YII2

прочитать json файл в YII2

подскажите как в Yii2 получить в js данные из JSON файла, который находится в одной и той же папке с файлом js, делал вот так но выдает ошибку(404):

196
Как можно сделать фильтрацию слов?

Как можно сделать фильтрацию слов?

На вход поступает слово,например:

179