How to call a fragment from BaseAdapter Class Andr

2020-02-10 08:20发布

问题:

I want to call a Fragement from my BaseAdapter Class. In this class I have button on click of which I want to call the new fragment, but I am not able to get this. I have to pass values from the click of the button to the fragment.

BaseAdapter Class

public class StatusAdapter extends BaseAdapter {

    private Activity activity;
    private ArrayList<HashMap<String, String>> data;
    private static LayoutInflater inflater = null;
    public StatusAdapter(Activity a,
            ArrayList<HashMap<String, String>> d) {
        activity = a;
        data = d;
        inflater = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return data.size();
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View vi = convertView;
        if (convertView == null)
            vi = inflater.inflate(R.layout.approval_selftrip_inner, null);
        TextView approved_by = (TextView) vi.findViewById(R.id.approved_by);
        TextView status = (TextView) vi.findViewById(R.id.status);
        TextView trip = (TextView) vi.findViewById(R.id.trip);
        Button view_log = (Button)vi.findViewById(R.id.view_log);

        HashMap<String, String> list = new HashMap<String, String>();
        list = data.get(position);
        approved_by.setText(list.get("first_id"));
        status.setText(list.get("status"));
        trip.setText(list.get("trip"));
        view_log.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

                //Here i want to call my fragment 

            }
        });
        return vi;
    }
}

Fragement

public class Log extends Fragment {
    Context context ;
    View rootView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        context = getActivity();

        rootView = inflater.inflate(R.layout.activity_log,
                container, false);
        return rootView;
    }


}

I want to call this Fragment from the BaseAdapter Class on click of view_log.Please help me how can we do this

After Martin Cazares I have done this

In Activity

public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
    context = getActivity();
        rootView = inflater.inflate(R.layout.activity_main,
                container, false);
        mBroadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                Toast.makeText(context, "Recived", 
                           Toast.LENGTH_LONG).show();
                ApprovalLog fragment2 = new ApprovalLog();
                FragmentManager fragmentManager = getFragmentManager();
                FragmentTransaction fragmentTransaction = fragmentManager
                        .beginTransaction();
                fragmentTransaction.replace(R.id.content_frame, fragment2);
                fragmentTransaction.commit();
            }
        };
        return rootView;
    } 

In The AdapterClass

view_approvallog.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                CommonUtils.showAlert("Test in Adapter", activity);
                activity.registerReceiver(mBroadcastReceiver, new IntentFilter(
                        "start.fragment.action"));

            }
        });

回答1:

Simply use this.

public void onClick(View view) {
 LogFrag fragment2 = new LogFrag();
 FragmentManager fragmentManager = getFragmentManager();
 FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
 fragmentTransaction.replace(R.id.fragment1, fragment2);
 fragmentTransaction.commit();
}


回答2:

Honestly if you have to call your fragment from a BaseAdapter something is terribly wrong with your application's architecture, you are tightly coupling components and Spaghetti Code will be a problem soon, if you want to keep it clean, make a listener or send a broadcast from it, and call your fragment from your activity as you usually do, the point is to keep components doing the job they are intended for and not having all in one single class, that's a terrible thing to do and code becomes less legible.

As explained a simple approach to decouple things in android is by sending broadcast messages, so this is one way of doing it:

 view_log.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {

            //Here i want to call my fragment
            //You need to pass a reference of the context to your adapter...
            context.sendBroadcast(new Intent("start.fragment.action"))

        }
    });

Now in your activity all you have to do is register a BroadcastReceiver with the "start.fragment.action" and that's it inside of it just call your fragment:

//In your activity...
context.registerReceiver(mBroadcastReceiver, new IntentFilter("start.fragment.action"))
.
.
.   
BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
                    //This piece of code will be executed when you click on your item
            // Call your fragment...
        }
    };

Do not forget to unregister when done, and if you need to pass some parameters to the fragment you can use extras in the intent when sending the broadcast message...

NOTE: LocalBroadcastManager would be better to use now.

Regards!



回答3:

Use

((Activity) mContext).getFragmentManager();//use this

view.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Fragment fragment = new CallThisFragment();
            FragmentManager fragmentManager = ((Activity) mContext).getFragmentManager();
            fragmentManager.beginTransaction().replace(R.id.main_activity, fragment).commit();
        }
    });    


回答4:

Easiest way: Do in Fragment

Adapter a = new Adapter(arg,Fragment.this);// or only this. This will pass the fragment object to the adapter.

and in Adapter

v.ckbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {


            if(fragment!=null)
                fragment.ValidateList();// call any public method of the fragment
            }
        });


回答5:

Parse FragmentManager xxx object to Adpter Constructor,

**xxx**.beginTransaction().replace(your_container, new YourNewFragment()).addToBackStack(null).commit();


回答6:

FragmentManager manager = ((AppCompatActivity) 
context).getSupportFragmentManager();
FragmentTransaction fragmentTransaction = manager.beginTransaction();
            fragmentTransaction.replace(R.id.content_frame, new AlbumFragment());
            fragmentTransaction.addToBackStack(null);
            fragmentTransaction.commit();


回答7:

Perfect way to call fragment from Custom Base Adapter

fragmentManager.beginTransaction()
        .add(R.id.content_frame, new YourFragmentName())
        .addToBackStack("fragBack")).commit();
((Activity) context).setTitle("Title For Action Bar");`