简体   繁体   English

如何将 object(在这种情况下为 arraylist)从一个片段发送到 java(Android)中的另一个片段

[英]How to send an object (an arraylist in this situation) from one fragment to another fragment in java (Android)

The title says it all.标题说明了一切。 I am attempting to send an ArrayList that has data inside from one fragment to another and then switch and show the second fragment (the one that just received the ArrayList).我正在尝试发送一个 ArrayList,其中包含从一个片段到另一个片段的数据,然后切换并显示第二个片段(刚刚收到 ArrayList 的片段)。

here is my MainActivity.java:这是我的 MainActivity.java:

package;

import android.os.Bundle;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;

import android.view.View;

import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;

import com.google.android.material.navigation.NavigationView;

import androidx.drawerlayout.widget.DrawerLayout;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import android.view.Menu;

public class MainActivity extends AppCompatActivity {

    private AppBarConfiguration mAppBarConfiguration;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        // Passing each menu ID as a set of Ids because each menu should be considered as top level destinations.
        mAppBarConfiguration = new AppBarConfiguration.Builder(
                R.id.nav_home, R.id.nav_display)
                .setDrawerLayout(drawer)
                .build();
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(navigationView, navController);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.navigateUp(navController, mAppBarConfiguration) || super.onSupportNavigateUp();
    }
}

here is my HomeFragment.java (the sending fragment):这是我的 HomeFragment.java (发送片段):

package;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.navigation.Navigation;

import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.ml.vision.FirebaseVision;
import com.google.firebase.ml.vision.common.FirebaseVisionImage;
import com.google.firebase.ml.vision.text.FirebaseVisionText;
import com.google.firebase.ml.vision.text.FirebaseVisionTextDetector;
import com.mvsolutions.snap.R;
import com.mvsolutions.snap.ui.display.DisplayFragment;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.Inflater;

import static android.app.Activity.RESULT_OK;

public class HomeFragment extends Fragment {


    private HomeViewModel homeViewModel;

    private ImageView imageView;
    private Button captureImageButton, detectButton, pickButton;
    private Bitmap imageBitmap;
    private TextView capturedTextView;
    static final int REQUEST_IMAGE_CAPTURE = 1;
    private static final int RESULT_LOAD_IMAGE = 101;

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

        //View view = inflater.inflate(R.layout.fragment_home, container, false);
        View root = inflater.inflate(R.layout.fragment_home, container, false);

        detectButton = root.findViewById(R.id.action_homeFragment_to_displayFragment2);
        //detectButton.setOnClickListener((View.OnClickListener) this);

        //return view;

        homeViewModel = ViewModelProviders.of(this).get(HomeViewModel.class);

        //View v = inflater.inflate(R.layout.fragment_display, container, false);
        imageView = root.findViewById(R.id.home_image_view_img);
        capturedTextView = root.findViewById(R.id.home_text_view_txt);
        captureImageButton = root.findViewById(R.id.capture_image_btn);
        detectButton = root.findViewById(R.id.detect_text_btn);
        //pickButton = root.findViewById(R.id.pick_image_btn);



        captureImageButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                captureImage();
            }
        });
//        pickButton.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                pickImage();
//            }
//        });
        detectButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Navigation.findNavController(v).navigate(R.id.action_homeFragment_to_displayFragment2);

//                DisplayFragment displayFragment = new DisplayFragment();
//                FragmentManager fragmentManager =  getFragmentManager();
//                fragmentManager.beginTransaction()
//                        .replace(R.id.DisplayFragment, displayFragment, displayFragment.getTag())
//                        .commit();


                //detectTextFromImage();
            }
        });
        return root;
    }

    private void detectTextFromImage() {
        capturedTextView.setText("");
        FirebaseVisionImage firebaseVisionImage = FirebaseVisionImage.fromBitmap(imageBitmap);
        FirebaseVisionTextDetector visionTextDetector = FirebaseVision.getInstance().getVisionTextDetector();
        visionTextDetector.detectInImage(firebaseVisionImage).addOnSuccessListener(new OnSuccessListener<FirebaseVisionText>() {
            @Override
            public void onSuccess(FirebaseVisionText firebaseVisionText) {
                List<FirebaseVisionText.Block> textBlocks = firebaseVisionText.getBlocks();
                if (textBlocks.size() == 0) {
                    Toast.makeText(getContext(), "No Text Found", Toast.LENGTH_SHORT).show();
                } else {
                    for (FirebaseVisionText.Block block : textBlocks) {
                        String text = block.getText();
                        ArrayList textBlobs = new ArrayList();
                        textBlobs.add(text);
                        for(int i = 0; i < textBlobs.size(); i++) {
                            capturedTextView.setText(capturedTextView.getText() + ",  " + textBlobs.get(i));
                        }
//                        capturedTextView.setText(capturedTextView.getText() + " " + text);
                    }
                }
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Toast.makeText(getContext(), "Something went wrong", Toast.LENGTH_SHORT).show();
                Log.d("Error", e.getMessage());
            }
        });
    }

    private void pickImage() {
        Intent i = new Intent(
                Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(i, RESULT_LOAD_IMAGE);
    }

    private void captureImage() {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
            Bundle extras = data.getExtras();
            imageBitmap = (Bitmap) extras.get("data");
            imageView.setImageBitmap(imageBitmap);
        }
//        else if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
//            Uri imageUri = data.getData();
//            imageBitmap = MediaStore.Images.Media.decodeBitmap(this.);
//            imageView.setImageBitmap(imageBitmap);
//        }
    }
}

here is my DisplayFragment.java (the receiving fragment):这是我的 DisplayFragment.java (接收片段):

package com.mvsolutions.snap.ui.display;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;

import com.mvsolutions.snap.R;

public class DisplayFragment extends Fragment {

    private DisplayViewModel DisplayViewModel;

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        DisplayViewModel =
                ViewModelProviders.of(this).get(DisplayViewModel.class);
        View root = inflater.inflate(R.layout.fragment_display, container, false);
//        final TextView textView = root.findViewById(R.id.text_gallery);
        DisplayViewModel.getText().observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {

            }
        });
        return root;
    }
}

I am currently using a navigation fragment xml file to make the button switch from the first fragment to the second, but I want it to send the data to the second fragment as well.我目前正在使用导航片段 xml 文件将按钮从第一个片段切换到第二个片段,但我希望它也将数据发送到第二个片段。 My two questions are:我的两个问题是:

  1. Is it possible to both send the data to the second fragment and switch to the second fragment with one button press?是否可以一键将数据发送到第二个片段并切换到第二个片段? or do I have to split it into two?还是我必须把它分成两部分?
  2. How do I send the data from the first fragment to the second?如何将数据从第一个片段发送到第二个片段?

You are using ViewModel so I think the easiest way is to use the same ViewModel for both fragments.您正在使用 ViewModel,所以我认为最简单的方法是对两个片段使用相同的 ViewModel。 In android docs, You can find an example Share data between fragments在 android 文档中,您可以找到一个在片段之间共享数据的示例

It's very common that two or more fragments in an activity need to communicate with each other.一个活动中的两个或多个片段需要相互通信是很常见的。 Imagine a common case of split-view (master-detail) fragments, where you have a fragment in which the user selects an item from a list and another fragment that displays the contents of the selected item.想象一下拆分视图(主-详细信息)片段的常见情况,其中您有一个片段,其中用户从列表中选择一个项目,另一个片段显示所选项目的内容。

public class SharedViewModel extends ViewModel {
    private final MutableLiveData<Item> selected = new MutableLiveData<Item>();

    public void select(Item item) {
        selected.setValue(item);
    }

    public LiveData<Item> getSelected() {
        return selected;
    }
}


public class MasterFragment extends Fragment {
    private SharedViewModel model;

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        itemSelector.setOnClickListener(item -> {
            model.select(item);
        });
    }
}

public class DetailFragment extends Fragment {

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        SharedViewModel model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        model.getSelected().observe(getViewLifecycleOwner(), { item ->
           // Update the UI.
        });
    }
}

Notice that both fragments retrieve the activity that contains them.请注意,两个片段都检索包含它们的活动。 That way, when the fragments each get the ViewModelProvider , they receive the same SharedViewModel instance, which is scoped to this activity.这样,当每个片段都获得ViewModelProvider时,它们会收到相同的SharedViewModel实例,该实例的作用域是这个活动。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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