简体   繁体   中英

Add Item to RecyclerView embebed in Fragment from Main Activity

I have the following problem: I have a main activity (MainActivity) that has a Nav Drawer from which I am loading different fragments.One of the fragments that it loads contains a recyclerView that shows a list of data (bicycles). Another fragment is responsible for adding bicycles to the list. The problem comes here: When I add a bike to the list, you have to reload the bike list with the new bike.I leave the code: Fragment ItemFragment: Responsible for showing the list of bikes

    public class ItemFragment extends Fragment {

// TODO: Customize parameter argument names
private static final String ARG_COLUMN_COUNT = "column-count";
// TODO: Customize parameters
private int mColumnCount = 1;
private OnListFragmentInteractionListener mListener;
private List<Bike> bikes;
private RecyclerView recyclerView;
private MyItemRecyclerViewAdapter myAdapter;
/**
 * Mandatory empty constructor for the fragment manager to instantiate the
 * fragment (e.g. upon screen orientation changes).
 */
public ItemFragment() {
    this.bikes = new ArrayList<Bike>();
}

// TODO: Customize parameter initialization
@SuppressWarnings("unused")
public static ItemFragment newInstance(int columnCount) {
    ItemFragment fragment = new ItemFragment();
    Bundle args = new Bundle();
    args.putInt(ARG_COLUMN_COUNT, columnCount);
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (getArguments() != null) {
        mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT);
    }

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_item_list, container, false);

    // Set the adapter
    if (view instanceof RecyclerView) {
        Context context = view.getContext();
        recyclerView = (RecyclerView) view;
        if (mColumnCount <= 1) {
            recyclerView.setLayoutManager(new LinearLayoutManager(context));
        } else {
            recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount));
        }
        this.bikes = new ArrayList<Bike>();
        bikes.add(new Bike("Bike1", "First Bike"));
        bikes.add(new Bike("Bike2", "Second Bike"));
        bikes.add(new Bike("Bike3", "Third Bike"));
        bikes.add(new Bike("Bike4", "Fourth Bike"));
        bikes.add(new Bike("Bike5", "Fifth Bike"));
        bikes.add(new Bike("Bike6", "Sixth Bike"));
        this.myAdapter = new MyItemRecyclerViewAdapter(bikes, mListener);
        recyclerView.setAdapter(myAdapter);
        ((MainActivity)this.getActivity()).shareFragment(this);

    }
    return view;
}



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

}


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

public void addBike(Bike bike) {
    this.bikes.add(bike);
    if (this.myAdapter!=null)
        this.myAdapter.notifyDataSetChanged();
}



/**
 * 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 OnListFragmentInteractionListener {
    // TODO: Update argument type and name
    void onListFragmentInteraction(Bike item);
}
}

AddBikeFragment: Adds a bike to the list

public class AddBikeFragment extends Fragment{
private OnClickListener listener;

private TextInputEditText mIdView;
private TextInputEditText mContentView;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    return inflater.inflate(R.layout.activity_add_bicycle,container,false);
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    mIdView=view.findViewById(R.id.idBike);
    mContentView=view.findViewById(R.id.content);
    Button mAddBike = (Button) view.findViewById(R.id.addBike);
    mAddBike.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            String idBike = mIdView.getText().toString();
            String content = mContentView.getText().toString();

            if (idBike!=null) {
                //Log.d("TDDM", " itemFragment -" + this.itemFragment + "-");

                Bike bike=new Bike(idBike, content);

                listener.addItem(bike);
            }

        }
    });
}

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

}

// Define the events that the fragment will use to communicate
public interface OnClickListener {
    // This can be any number of events to be sent to the activity
    void addItem(Bike bike);
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof OnClickListener) {
        listener = (OnClickListener) context;
    } else {
        throw new ClassCastException(context.toString()
                + " must implement AddBikeFragment.OnClickListener");
    }


}

MainActivity: Responsible for loading the fragments and operating with them

public class MainActivity extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener, ItemFragment.OnListFragmentInteractionListener, AddBikeFragment.OnClickListener, MapFragment.OnFragmentInteractionListener, CitiesFragment.OnListFragmentInteractionListener {

private Fragment fragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main2);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);



    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.addDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);


}

@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else {
        super.onBackPressed();
    }
}

Please, can anyone guide me? I think I have the problem in the addItem method of MainActivity, where I instancio a new ItemFragment, and the listener is empty, how do I do it? Thank you

One way to do it is to save the list of bikes in a singleton:

public class BikeData{

    private static BikeData single_instance = null; 
    private List<Bike> bikes;

       public static BikeData getInstance() 
        { 
            if (single_instance == null)single_instance = new BikeData(); 

            return single_instance; 
        } 
    } 

    }

Then create methods to add, remove or retrieve a bike. eg

public static List<Bike> getBikeData(){
return bikes;
}

When adding a bike you will need to update the adapter.

In your fragment you can call adapter.notifyDataSetChanged() and reset the adapter:

recyclerview.setAdapter(adapter)

Also worth mentioning you can easily commuincate between fragments with the aid of eventBus .

Hope that helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM