Florian Walther
Florian Walther

Reputation: 6971

Android: Getting information out of an Adapter

I have a ListView connected to a CustomAdapter. Within the Adapter class, i have listeners for the different Views. When something changes, it updates the values of the ListItem over

currentItem.myListItemMethod()

Now i dont know how to get that information back into the Fragment that holds the ListView. I tried

adapter.registerDataSetObserver

in the Fragment, but it doesnt react to any of the changes within the Adapter. Only to changes from the Fragment itself (like clicking a Button that adds a new Item).

Also i want to know how i can get a reference to the most up-to-date ArrayList within the Adapter class, so i can return it to the Fragment.

I hope my question was understandable, i am new to programming.

EDIT:

Here my Fragment with the 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();
    }

}

And this is the Adapter

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

}

Upvotes: 0

Views: 185

Answers (1)

Muthukrishnan Rajendran
Muthukrishnan Rajendran

Reputation: 11622

You can create one interface in the Adapter Class, and you can implement that interface in your fragment and set that to Adapter So that when ever any changes happen in the adapter you can notify the Fragment.

Also i want to know how i can get a reference to the most up-to-date ArrayList within the Adapter class, so i can return it to the Fragment

For this, we can use default method getItem(position)

So create on method like this in adapter class and you can get the complete list

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 Create one Interface like this in Adapter class

public interface OnAdapterItemActionListener {
    public void onStarItemClicked(int position);
    public void onSeekBarChage(int position, int progress);
    //.. and you can add more method like this
}

add this interface in your constructor of you Adapter, and hold that object in the 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;
    }
}

Now in your fragment you should implement this interface like below

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

And while creating the adapter object you should send the interface implementation too, Because in Adapter constructor we are expecting that, so change this,

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

Above code will finish the interface setup, Now we should trigger the interface at right time like below,

When user click on star button, we should trigger like this,

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

Upvotes: 2

Related Questions