Android:从适配器中获取信息

时间:2017-08-08 19:40:15

标签: java android android-adapter

我有一个连接到CustomAdapter的ListView。在Adapter类中,我有不同视图的监听器。当某些内容发生变化时,它会更新ListItem的值

currentItem.myListItemMethod()

现在我不知道如何将这些信息反馈到包含ListView的Fragment中。我试过了

adapter.registerDataSetObserver
片段中的

,但它不会对适配器中的任何更改做出反应。仅限片段本身的更改(例如单击添加新项目的按钮)。

另外我想知道如何在Adapter类中获得对最新ArrayList的引用,所以我可以将它返回到Fragment。

我希望我的问题是可以理解的,我是编程新手。

修改

这里我的片段与ListView

public class SettingsWindow extends Fragment {

    private ArrayList<IncentiveItem> mIncentiveList;

    private OnFragmentInteractionListener mListener;

    ListView incentiveList;

    IncentiveAdapter adapter;

    public SettingsWindow() {
        // Required empty public constructor
    }


    public static SettingsWindow newInstance(ArrayList<IncentiveItem> incentiveList) {
        SettingsWindow fragment = new SettingsWindow();
        Bundle args = new Bundle();
        args.putSerializable("Incentive List", incentiveList);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mIncentiveList = (ArrayList<IncentiveItem>) getArguments().getSerializable("Incentive List");
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        final View inf = inflater.inflate(R.layout.fragment_settings_window, container, false);
        incentiveList = (ListView) inf.findViewById(R.id.incentive_list_xml);

        adapter = new IncentiveAdapter(getActivity(), mIncentiveList);

        incentiveList.setAdapter(adapter);

        return inf;
    }



    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    /**
     * This interface must be implemented by activities that contain this
     * fragment to allow an interaction in this fragment to be communicated
     * to the activity and potentially other fragments contained in that
     * activity.
     * <p>
     * See the Android Training lesson <a href=
     * "http://developer.android.com/training/basics/fragments/communicating.html"
     * >Communicating with Other Fragments</a> for more information.
     */
    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);
    }

    public void addIncentive() {
        mIncentiveList.add(new IncentiveItem());
        adapter.notifyDataSetChanged();
    }

}

这是适配器

public class IncentiveAdapter extends ArrayAdapter<IncentiveItem> {


    public IncentiveAdapter(Activity context, ArrayList<IncentiveItem> incentiveList) {
        super(context, 0, incentiveList);
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        View listItemView = convertView;
        if (listItemView == null) {
            listItemView = LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false);
        }

        final IncentiveItem currentItem = getItem(position);

        //We get references for the Views within the Incentive Item
        final ImageView star = (ImageView) listItemView.findViewById(R.id.star_xml);
        final EditText description = (EditText) listItemView.findViewById(R.id.incentive_text_xml);
        SeekBar seekBar = (SeekBar) listItemView.findViewById(R.id.seekbar_xml);
        final TextView percentage = (TextView) listItemView.findViewById(R.id.seekbar_percentage_xml);

        star.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (currentItem.getActiveOrInactive() == false) {
                    currentItem.setActive();
                    star.setImageResource(R.drawable.ic_star_active);
                } else {
                    currentItem.setInActive();
                    star.setImageResource(R.drawable.ic_star_inactive);;
                }
            }
        });

        description.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                currentItem.setText(description.getText().toString());
            }

            @Override
            public void afterTextChanged(Editable editable) {

            }
        });

        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean b) {
                percentage.setText("" + progress + "%");
                currentItem.setProbabilityInPercent(progress);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

        return listItemView;
    }

}

1 个答案:

答案 0 :(得分:1)

您可以在Adapter Class中创建一个interface,并且可以在片段中实现该接口并将其设置为Adapter。当适配器中发生任何更改时,您可以通知片段。

  

此外,我想知道如何获得最新的参考   Adapter类中的ArrayList,所以我可以将它返回到Fragment

为此,我们可以使用默认方法getItem(position)

所以在适配器类中创建这样的方法,你就可以得到完整的列表

public ArrayList<IncentiveItem> getItemValues() {
    ArrayList<IncentiveItem> incentiveList  = new ArrayList<IncentiveItem>();
    for (int i=0 ; i < getCount() ; i++){
        IncentiveItem incentiveItem = getItem(i);
        incentiveList.add(incentiveItem);
    }
    return incentiveList;
}

<强> EDITED 在Adapter类

中创建一个这样的接口
public interface OnAdapterItemActionListener {
    public void onStarItemClicked(int position);
    public void onSeekBarChage(int position, int progress);
    //.. and you can add more method like this
}

在您的Adapter的构造函数中添加此接口,并将该对象保存在适配器

public class IncentiveAdapter extends ArrayAdapter<IncentiveItem> {

    private OnAdapterItemActionListener mListener;
    public IncentiveAdapter(Activity context, ArrayList<IncentiveItem> incentiveList, OnAdapterItemActionListener listener) {
        super(context, 0, incentiveList);
        mListener = listener;
    }
}

现在,在您的片段中,您应该实现此界面,如下所示

public class SettingsWindow extends Fragment implements OnAdapterItemActionListener{
    @Overrride
    public void onStarItemClicked(int position) {
        // You will get callback here when click in adapter
    }

    @Overrride
    public void onSeekBarChage(int position, int progress) {
        // You will get callback here when seekbar changed
    }
}

在创建适配器对象时,您也应该发送接口实现,因为在Adapter构造函数中我们期望这样,所以更改它,

adapter = new IncentiveAdapter(getActivity(), mIncentiveList, this); // this - Because we implemented in this class

上面的代码将完成界面设置,现在我们应该在适当的时候触发界面,如下所示,

当用户点击星形按钮时,我们应该这样触发,

star.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //Your code here
                if(mListener != null) { //Just for safety check
                    mListener.onStarItemClicked(position);// this will send the callback to your Fragment implementation
                }
            }
        });