简体   繁体   中英

How to use setContentView in fragment instead of an activity

Dear Stackoverflowers:)

AllAssetsFragment is opened from the MainActivity. In this fragment, I have trouble setting up the setContentView() and getApplicationContext() properly.

I know there is something wrong. Some of the code works for normal activities but they are not working in this fragment.


AllAssetsFragment:

import android.content.Intent;
import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.room.Room;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;


public class AllAssetsFragment extends Fragment {

    public AllAssetsFragment(){


    }


    private static final String HI = "https://uniqueandrocode.000webhostapp.com/hiren/favouritelist.php";
    private List<AssetsItem>assetsItems;
    private RecyclerView recyclerView;
    AssetsAdapter adapter;

    private JsonArrayRequest request;
    private RequestQueue requestQueue;
    public static FavoritesDatabase favoritesDatabase;
    Button btn;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        return inflater.inflate(R.layout.fragment_allassets, container, false);


        recyclerView = (RecyclerView)getView().findViewById(R.id.recyclerview);
        recyclerView.setHasFixedSize(true);
        // +++ PROBLEM 1: Context doesn't work (same on Problem 3 and 4) +++
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        assetsItems = new ArrayList<>();
        btn=(Button)getView().findViewById(R.id.favbtn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // +++ PROBLEM 2: This code doesn't work to open Fragment from Fragment +++
                startActivity(new Intent(AllAssetsFragment.this, FavoritesFragment.class));
            }


        });
        favoritesDatabase = Room.databaseBuilder(getActivity().getApplicationContext(), FavoritesDatabase.class, "myfavdb").allowMainThreadQueries().build();
        getData();

    }

    private void getData() {
        request = new JsonArrayRequest(HI, new Response.Listener<JSONArray>() {
            @Override
            public void onResponse(JSONArray response) {
                JSONObject jsonObject = null;
                for (int i = 0; i < response.length(); i++) {
                    try {
                        JSONObject ob = response.getJSONObject(i);
                        AssetsItem pr = new AssetsItem(ob.getInt("id"),
                                ob.getString("product_name"),
                                ob.getString("product_img"));
                        assetsItems.add(pr);

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
                setupData(assetsItems);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        });

        // +++ PROBLEM 3: Context doesn't work +++
        requestQueue = Volley.newRequestQueue(this);
        requestQueue.add(request);
    }

    private void setupData(List<AssetsItem>assetsItems){
    adapter=new AssetsAdapter(assetsItems,getActivity().getApplicationContext());
    recyclerView.setAdapter(adapter);
    }
}

And here our 2nd Fragment: FavoritesFragment:



import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.List;


/**
 * A simple {@link Fragment} subclass.
 */
public class FavoritesFragment extends Fragment {


    public FavoritesFragment() {

    }

    private RecyclerView rv;
    private FavoritesAdapter adapter;

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        return inflater.inflate(R.layout.fragment_favorites, container, false);

        rv=(RecyclerView)getView().findViewById(R.id.rec);
        rv.setHasFixedSize(true);
        // +++ PROBLEM 4: doesn't work +++
        rv.setLayoutManager(new LinearLayoutManager(this));

        getFavData();
    }

    private void getFavData(){
        List<FavoritesItem>favoritesItems=AllAssetsFragment.favoritesDatabase.favoritesDao().getFavoritesData();

        adapter = new FavoritesAdapter(favoritesItems,getActivity().getApplicationContext());
        rv.setAdapter(adapter);
    }



}

Don't use setContentView() within fragments. You should init your view in onCreateView() , like you already do.

About application context, I see that you are passing it to your adapter. I would argue that you don't need the application context there, as the context of the fragment should be enough. You can pass requireContext() .

You will also need to setup your RecyclerView and adapter from onCreateView() .

These are the mistakes you made in your code.

AllAssetsFragment

  • Move the line below to the bottom of the onCreateView() method. It is a return statement, therefore, it has to be the last thing in the function.

     return inflater.inflate(R.layout.fragment_allassets, container, false);
  • You can't use startActivity(...) to launch a fragment. This method is strictly for launching activities. To learn how to launch a fragment, check this awesome answer out.

  • Replace this with getActivity() in the lines below:

    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    requestQueue = Volley.newRequestQueue(this);

FavoritesFragment

  • Replace this with getActivity() in the line below:

    rv.setLayoutManager(new LinearLayoutManager(this));

Addendum:

To launch a fragment within an activity (in your case, MainActivity), follow the following steps:

  1. In your activity_main.xml file, create a FrameLayout that would house your fragment, you can give it an id: container . If you don't know how to do this, just paste the code below:

     <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/container" />
  2. When you want to launch a fragment from an activity, simply use this code snippet:

     FragmentTransaction transaction = getFragmentManager().beginTransaction(); transaction.replace(R.id.container, new AllAssetsFragment()); transaction.commit();
  3. When you want to launch a fragment from another fragment, simply use this code snippet:

     FragmentTransaction transaction = getActivity().getFragmentManager().beginTransaction(); transaction.replace(R.id.container, new AllAssetsFragment()); transaction.commit();
  4. In the code snippets above, if getFragmentManager() does not work or if you are using AndroidX, use getSupportFragmentManager() instead.

You don't call setContentView in fragments you need return view in onCreateView method. you have already done.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_allassets, container, false);
}

and for getApplicationContext you need to call getActivity()

like this

getActivity().getApplicationContext()

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