在主活动中监听片段的onClick事件

4
在主活动中,我正在创建一个 PagerAdapter 并用 Fragments 填充它。现在我想监听主 Activity 中的点击事件。我该怎么做?
来自主活动的部分。
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager(), this, audioList);
viewPager.setAdapter(pagerAdapter);

// Give the TabLayout the ViewPager
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(viewPager);

// Iterate over all tabs and set the custom view
for (int i = 0; i < tabLayout.getTabCount(); i++) {
    TabLayout.Tab tab = tabLayout.getTabAt(i);
    tab.setCustomView(pagerAdapter.getTabView(i));
}

// Listen to onClicksHere
//
// songListFragment.setItemOnClickListener(audio -> {
//     goToCameraView();
//     songGraph.setAudio(audio);
// });

PagerAdapter:

public class PagerAdapter extends FragmentStatePagerAdapter {

    String tabTitles[] = new String[]{"Recommended", "Popular", "Rock", "Pop", "Blues", "Chill"};
    Context context;
    private ArrayList<Audio> audioList;

    public PagerAdapter(FragmentManager fm, Context context, ArrayList<Audio> audioList) {
        super(fm);
        this.context = context;
        this.audioList = audioList;
    }

    @Override
    public int getCount() {
        return tabTitles.length;
    }

    @Override
    public Fragment getItem(int position) {
        return SongList.newInstance(audioList);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        // Generate title based on item position
        return tabTitles[position];
    }

    public View getTabView(int position) {
        View tab = LayoutInflater.from(context).inflate(R.layout.custom_tab, null);
        TextView tv = (TextView) tab.findViewById(R.id.custom_text);
        tv.setText(tabTitles[position]);
        return tab;
    }

}

SongListFragment:

public class SongListFragment extends Fragment {

    FragmentManager fm;
    RecyclerView songListView;

    Audio selectedAudio;

    SongListItemOnClickListener listener;

    /**
     * Initialization logic goes here
     * @param savedInstanceState
     */
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    /**
     * Creates songlist view object
     * @param inflater
     * @param container
     * @param savedInstanceState
     * @return
     */
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        songListView = (RecyclerView) inflater.inflate(R.layout.songgraph_songlist, container, false);
        songListView.setLayoutManager(new LinearLayoutManager(getActivity()));
        songListView.setAdapter(new SongListAdapter(getArguments().getParcelableArrayList("audioList")));
        return songListView;
    }

    /**
     * Creates new instance of songlist fragment with arguments
     * @param audio - Audio list for this fragment to display
     * @return
     */
    public static SongListFragment newInstance(ArrayList<Audio> audio) {
        SongListFragment fragment = new SongListFragment();
        Bundle args = new Bundle();
        args.putParcelableArrayList("audioList", audio);
        fragment.setArguments(args);
        return fragment;
    }

    /**
     *  Adapter for songlist items
     */
    public class SongListAdapter extends RecyclerView.Adapter<SongListItemViewHolder> {

        ArrayList<Audio> audioList;

        public SongListAdapter(ArrayList<Audio> audioList) {
            this.audioList = audioList;
        }

        @Override
        public SongListItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            Context context = parent.getContext();
            LayoutInflater inflater = LayoutInflater.from(context);
            View contactView = inflater.inflate(R.layout.songgraph_songlist_item, parent, false);
            SongListItemViewHolder viewHolder = new SongListItemViewHolder(contactView);
            return viewHolder;
        }

        @Override
        public void onBindViewHolder(SongListItemViewHolder holder, int position) {
            Audio audio = audioList.get(position);
            holder.title.setText(audio.getTitle());
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    selectedAudio = audio;

                    if (listener != null) {
                        listener.onClick(audio);
                    }
                }
            });
        }

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

    }

    public static class SongListItemViewHolder extends RecyclerView.ViewHolder {

        public TextView title;

        public SongListItemViewHolder(View itemView) {
            super(itemView);
            title = itemView.findViewById(R.id.songlist_item_title);
        }

    }

    public Audio getSelectedAudio() {
        return selectedAudio;
    }

    public void setItemOnClickListener(SongListItemOnClickListener listener) {
        this.listener = listener;
    }

    /** Interface for listener **/
    public interface SongListItemOnClickListener {
        void onClick(Audio audio);
    }

}
1个回答

4

不要在Activity中创建监听器,应该在Activity中实现监听器方法,并使用Fragment的onAttach / onDetach方法将Activity注册/注销为回调。

这种方法的优点是,在配置更改后,Activity会重新注册为监听器。

活动:

public MainActivty extends ... implements OnSongClickListener {

    ...

    public void onSongClicked(Audio audio) {
        ...
    }

}

碎片:

public SongListFragment extends ... {

    private OnSongClickListener mListener;

    ...

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        // Set parent activity as callback
        try {
            mListener = (OnSongClickListener) context;
        } catch (ClassCastException e) {
            throw new ClassCastException(context.toString()
                + " must implement " + OnSongClickListener.class.getName());
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();

        // Reset callback
        mListener = null;
    }

    ...

        @Override
        public void onBindViewHolder(SongListItemViewHolder holder, int position) {
            Audio audio = audioList.get(position);
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mListener != null) {
                        mListener.onSongClick(audio);
                    }
                }
            });
        }

    ...

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接