zoukankan      html  css  js  c++  java
  • Fragments之间的交互(实现参数传递)

    Fragments之间的交互(实现参数传递)

    日常开发中,通常Fragments之间可能需要交互,比如基于用户事件改变Fragment的内容。所有Fragment之间的交互需要通过他们关联的Activity,两个Fragment之间不应该直接交互。
    采用接口回调的方式来实现Fragments之间的交互,大致分为四步:

    1.定义一个接口

    • 为了让Fragment与Activity交互,可以在Fragment类中定义一个接口,并在Activity中实现。Fragment在它们的生命周期的onAttach()方法中获取接口的实现,然后调用接口的方法来与Activity交互。

    定义接口的代码如下:

    public class ListFragment extends Fragment implements AdapterView.OnItemClickListener {
    
        private ListView mListView;
        private ListAdapter mAdapter;
        private List<String> mData;
    
        public ListFragment() {
            // Required empty public constructor
        }
    
        public static ListFragment newInstance(String type) {
            Bundle args = new Bundle();
            args.putString("type", type);
            ListFragment fragment = new ListFragment();
            fragment.setArguments(args);
            return fragment;
        }
    
        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            if (mData == null) {
                mData = new ArrayList<>();
            }
            loadData();
        }
    
        private void loadData() {
            for (int i = 0; i < 10; i++) {
                mData.add("Item" + i);
            }
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            View rootView = inflater.inflate(R.layout.fragment_list, container, false);
            mListView = (ListView) rootView.findViewById(R.id.list_view);
    
            mAdapter = new ListAdapter(getActivity(), mData);
            mListView.setAdapter(mAdapter);
            mListView.setOnItemClickListener(this);
            return rootView;
        }
    
        @Override
        public void onAttach(Context context) {
            super.onAttach(context);
            // This makes sure that the container activity has implemented
            // the callback interface. If not, it throws an exception
            try {
                mOnListItemSelectedListener = (OnListItemSelectedListener) context;
            } catch (ClassCastException e) {
                throw new ClassCastException(context.toString()
                        + " must implement OnListItemSelectedListener");
            }
        }
    
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            mOnListItemSelectedListener.onListItemSelected(position);
        }
    
        private OnListItemSelectedListener mOnListItemSelectedListener;
    
        public interface OnListItemSelectedListener {
            void onListItemSelected(int position);
        }
    
    
        /* ================适配器相关===============*/
        public class ListAdapter extends BaseAdapter {
    
            private List<String> mData;
            private Context mContext;
    
            public ListAdapter(Context context, List<String> data) {
                this.mContext = context;
                this.mData = data;
            }
    
            @Override
            public int getCount() {
                return mData.size() == 0 ? 0 : mData.size();
            }
    
            @Override
            public Object getItem(int position) {
                return mData == null ? null : mData.get(position);
            }
    
            @Override
            public long getItemId(int position) {
                return position;
            }
    
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                ViewHolder holder;
                if (convertView == null) {
                    holder = new ViewHolder();
                    convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list, parent, false);
                    holder.mTextView = (TextView) convertView.findViewById(R.id.text_view);
                    convertView.setTag(holder);
                } else {
                    holder = (ViewHolder) convertView.getTag();
                }
                String text = mData.get(position);
                if (text != null && !"".equals(text)) {
                    holder.mTextView.setText(text);
                }
                return convertView;
            }
    
            public class ViewHolder {
                TextView mTextView;
            }
        }
    
    }
    
    • 现在Fragment就可以通过OnListItemSelectedListener 接口实例的mOnListItemSelectedListener中的onListItemSelected()方法与Activity传递消息。
    • 我这个例子实现的是在ListFragment中点击ListView的一个Item,把这个Item的position传递给DetailFragment,DetailFragment展示具体的信息,如新闻列表,点击Item之后进入新闻详情页。
    • 当我们点击Item时,ListFragment用回调接口来传递事件给父Activity。
     @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            mOnListItemSelectedListener.onListItemSelected(position);
        }
    

    2.实现接口

    • 为了接收回调事件,宿主Activity必须实现Fragment中定义的接口。
    • MainActivity实现了ListFragment中的接口,如下代码:
    public class MainActivity extends AppCompatActivity 
            implements ListFragment.OnListItemSelectedListener {
    
        private static final String TAG = "MainActivity";
    
        private ListFragment mListFragment;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mListFragment = ListFragment.newInstance("ListFragment");
            ActivityUtil.addFragmentToActivity(getSupportFragmentManager(),
                    mListFragment, R.id.frame_container);
        }
    
        @Override
        public void onListItemSelected(int position) {
            Log.d(TAG, position + "");
            Bundle args = new Bundle();
            args.putInt("position",position);
            DetailFragment fragment = DetailFragment.newInstance("DetailFragment");
            fragment.setArguments(args);
            ActivityUtil.addFragmentToActivity(getSupportFragmentManager(), fragment, R.id.frame_container);
        }
    }
    

    3.传递消息给Fragment

    • 宿主MainActivity中还包含了另外一个Fragment(DetailFragment),DetailFragment用来展示回调方法中指定Item的内容。在这种情况下,MainActivity可以把回调方法中接收到的position传递给DetailFragment。
     @Override
        public void onListItemSelected(int position) {
            Log.d(TAG, position + "");
            Bundle args = new Bundle();
            args.putInt("position",position);
            DetailFragment fragment = DetailFragment.newInstance("DetailFragment");
            fragment.setArguments(args);
            ActivityUtil.addFragmentToActivity(getSupportFragmentManager(), fragment, R.id.frame_container);
        }
    

    4.接收传递的参数

    • 在DetailFragment中接收ListFragment传递的position参数
    public class DetailFragment extends Fragment {
    
        private TextView mTextView;
        private Bundle args;
    
        public DetailFragment() {
            // Required empty public constructor
        }
    
        public static DetailFragment newInstance(String type) {
            Bundle args = new Bundle();
            args.putString("type", type);
            DetailFragment fragment = new DetailFragment();
            fragment.setArguments(args);
            return fragment;
        }
    
        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            args = getArguments();//获取传递的参数
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            View rootView = inflater.inflate(R.layout.fragment_detail, container, false);
            mTextView = (TextView) rootView.findViewById(R.id.text_view);
            mTextView.setText(args.get("position").toString());
            return rootView;
        }
    }
    

    这样就实现了两个Fragment之间的交互。其核心就是拥有同一个宿主Activity的Fragments利用接口回调的方式实现参数的传递。

    博客地址:http://tonycheng93.github.io/
    源码地址:https://github.com/tonycheng93/Fragment2Fragment

  • 相关阅读:
    Spring框架介绍及使用
    SpringMVC 网站
    Maven网站
    mysql数据库忘记密码时如何修改
    搭建ssm的步骤
    maven私服 Nexus2.x.x私服安装配置
    搭建聚合工程教案
    SVN上传下载项目
    如何区分不同用户——Cookie/Session机制详解
    java中Token验证
  • 原文地址:https://www.cnblogs.com/tonycheng93/p/5944508.html
Copyright © 2011-2022 走看看