如何使用 LocalBroadcastManager 调用不同的方法

4
我在动作栏上有三个菜单按钮(add_image,save_memeshare_meme),它们在Mainactivity.java中声明。这些按钮负责调用另一个片段中相应的方法。使用LocalBroadcastManager建立连接。
public class MainActivity extends AppCompatActivity{
    Intent saveIntent, shareIntent, addImageIntent;
    LocalBroadcastManager localBroadcastManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        localBroadcastManager = LocalBroadcastManager.getInstance(getApplicationContext());

        addImageIntent = new Intent("ADD_ACTION");
        saveIntent = new Intent("SAVE_ACTION");
        shareIntent = new Intent("SHARE_ACTION");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.add_image:
                localBroadcastManager.sendBroadcast(addImageIntent);
            case R.id.save_meme:
                localBroadcastManager.sendBroadcast(saveIntent);
            case R.id.share_meme:
                localBroadcastManager.sendBroadcast(shareIntent);
            default:
                return super.onOptionsItemSelected(item);
        }
    }
}

如上所述,相应的方法在TopImageFragment.java类中。 add_image按钮调用该方法,允许用户从设备上传图像到ImageView

public void selectedImage() {
    Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
    startActivityForResult(intent, PICK_IMAGE);
}

save_meme按钮调用保存位图到设备的方法:

public void saveMeme(Bitmap btm) {
        counter++;

        File file;
        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);

        String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath();
        file = new File(path + "/Memery/" + timeStamp + counter + ".jpg");
        file.getParentFile().mkdir();

        try {
            OutputStream stream = new FileOutputStream(file);
            btm.compress(Bitmap.CompressFormat.JPEG, 100, stream);
            stream.flush();
            stream.close();
            Toast.makeText(getContext(), "Meme Saved", Toast.LENGTH_SHORT).show();
        } catch (IOException e) {
            e.printStackTrace();
        }

        Uri contentUri = Uri.fromFile(file);
        mediaScanIntent.setData(contentUri);
        Objects.requireNonNull(getContext()).sendBroadcast(mediaScanIntent);
    }

share_meme 按钮调用了一个方法,使得用户可以在各种社交媒体应用程序和电子邮件客户端上分享这个“meme”:

public void shareMeme(Bitmap bitmap) {
    String path = MediaStore.Images.Media.insertImage(Objects.requireNonNull(getContext()).getContentResolver(), bitmap, "Meme", null);
    Uri uri = Uri.parse(path);

    Intent share = new Intent(Intent.ACTION_SEND);
    share.setType("image/*");
    share.putExtra(Intent.EXTRA_STREAM, uri);
    share.putExtra(Intent.EXTRA_TEXT, "This is my Meme");
    getContext().startActivity(Intent.createChooser(share, "Share Your Meme!"));
}

但现在发生的情况是,无论我选择哪个3个菜单按钮中的哪一个,都会调用所有3个方法。这是我的完整片段:

public class TopImageFragment extends Fragment {

    ImageView imageView;
    TextView topTextView, bottomTextView;
    RelativeLayout topImageRelativeLayout;
    public static final int PICK_IMAGE = 1;
    Uri imageUri;
    int counter = 0;
    String timeStamp = new SimpleDateFormat("yyyyMMdd", Locale.CANADA).format(new Date());
    float textSize, x, imageViewArea, canvasArea;
    double val;


    MemeViewModel memeViewModel;

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

        imageView = view.findViewById(R.id.meme_image_view);

        topTextView = view.findViewById(R.id.top_text_view);
        bottomTextView = view.findViewById(R.id.bottom_text_view);

        topImageRelativeLayout = view.findViewById(R.id.top_image_relative_layout);

        if (savedInstanceState != null) {
            imageUri = savedInstanceState.getParcelable("imageUri");
            imageView.setImageURI(imageUri);
        }
        return view;
    }

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelable("imageUri", imageUri);
    }

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

        memeViewModel = ViewModelProviders.of(Objects.requireNonNull(getActivity())).get(MemeViewModel.class);

        memeViewModel.getTopText().observe(getViewLifecycleOwner(), new Observer<CharSequence>() {
            @Override
            public void onChanged(@Nullable CharSequence charSequence) {
                topTextView.setText(charSequence);
            }
        });

        memeViewModel.getBottomText().observe(getViewLifecycleOwner(), new Observer<CharSequence>() {
            @Override
            public void onChanged(@Nullable CharSequence charSequence) {
                bottomTextView.setText(charSequence);
            }
        });
    }

    public void selectedImage() {
        Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
        startActivityForResult(intent, PICK_IMAGE);
    }

    public Bitmap getBitmap(ImageView img) {
        BitmapDrawable bitmapDrawable = ((BitmapDrawable) img.getDrawable());
        Bitmap bitmap = bitmapDrawable.getBitmap();

        return bitmap.copy(Bitmap.Config.ARGB_8888, true);
    }

    public Bitmap screenshotMeme() {
        Bitmap image = Bitmap.createBitmap(topImageRelativeLayout.getWidth(), topImageRelativeLayout.getHeight(), Bitmap.Config.RGB_565);
        topImageRelativeLayout.draw(new Canvas(image));

        return image.copy(Bitmap.Config.ARGB_8888, true);
    }

    public Bitmap drawMeme(Bitmap mutableBitmap) {

        String topText = topTextView.getText().toString();
        String bottomText = bottomTextView.getText().toString();

        topText = topText.toUpperCase();
        bottomText = bottomText.toUpperCase();

        Canvas canvas = new Canvas(mutableBitmap);

        TextPaint topFillPaint = new TextPaint();
        TextPaint bottomFillPaint = new TextPaint();

        TextPaint topStrokePaint = new TextPaint();
        TextPaint bottomStrokePaint = new TextPaint();

        Typeface typeface = getResources().getFont(R.font.impact);

        textSize = topTextView.getTextSize();
        imageViewArea = (imageView.getWidth()) * (imageView.getHeight());
        canvasArea = (canvas.getWidth()) * (canvas.getHeight());
        val = textSize * sqrt(canvasArea / imageViewArea);
        x = (float) val;

        topFillPaint.setColor(Color.WHITE);
        topFillPaint.setTextSize(x);
        topFillPaint.setTypeface(typeface);
        topFillPaint.setStyle(Paint.Style.FILL_AND_STROKE);

        topStrokePaint.setStyle(Paint.Style.STROKE);
        topStrokePaint.setStrokeWidth(4);
        topStrokePaint.setTextSize(x);
        topStrokePaint.setColor(Color.BLACK);
        topStrokePaint.setTypeface(typeface);

        bottomFillPaint.setColor(Color.WHITE);
        bottomFillPaint.setTextSize(x);
        bottomFillPaint.setTypeface(typeface);
        bottomFillPaint.setStyle(Paint.Style.FILL_AND_STROKE);

        bottomStrokePaint.setStyle(Paint.Style.STROKE);
        bottomStrokePaint.setStrokeWidth(4);
        bottomStrokePaint.setColor(Color.BLACK);
        bottomStrokePaint.setTextSize(x);
        bottomStrokePaint.setTypeface(typeface);

        StaticLayout topFillLayout = new StaticLayout(topText, topFillPaint, canvas.getWidth(), Layout.Alignment.ALIGN_CENTER,
                0.8f, 0.0f, false);
        StaticLayout topStrokeLayout = new StaticLayout(topText, topStrokePaint, canvas.getWidth(), Layout.Alignment.ALIGN_CENTER,
                0.8f, 0.0f, false);
        StaticLayout bottomFillLayout = new StaticLayout(bottomText, bottomFillPaint, canvas.getWidth(), Layout.Alignment.ALIGN_CENTER,
                0.8f, 0.0f, false);
        StaticLayout bottomStrokeLayout = new StaticLayout(bottomText, bottomStrokePaint, canvas.getWidth(), Layout.Alignment.ALIGN_CENTER,
                0.8f, 0.0f, false);

        topFillLayout.draw(canvas);

        topStrokeLayout.draw(canvas);

        canvas.translate(0, canvas.getHeight() - bottomFillLayout.getHeight());
        bottomFillLayout.draw(canvas);

        bottomStrokeLayout.draw(canvas);

        return mutableBitmap;
    }

    public void saveMeme(Bitmap btm) {
        counter++;

        File file;
        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);

        String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath();
        file = new File(path + "/Memery/" + timeStamp + counter + ".jpg");
        file.getParentFile().mkdir();

        try {
            OutputStream stream = new FileOutputStream(file);
            btm.compress(Bitmap.CompressFormat.JPEG, 100, stream);
            stream.flush();
            stream.close();
            Toast.makeText(getContext(), "Meme Saved", Toast.LENGTH_SHORT).show();
        } catch (IOException e) {
            e.printStackTrace();
        }

        Uri contentUri = Uri.fromFile(file);
        mediaScanIntent.setData(contentUri);
        Objects.requireNonNull(getContext()).sendBroadcast(mediaScanIntent);
    }

    public void shareMeme(Bitmap bitmap) {
        String path = MediaStore.Images.Media.insertImage(Objects.requireNonNull(getContext()).getContentResolver(), bitmap, "Meme", null);
        Uri uri = Uri.parse(path);

        Intent share = new Intent(Intent.ACTION_SEND);
        share.setType("image/*");
        share.putExtra(Intent.EXTRA_STREAM, uri);
        share.putExtra(Intent.EXTRA_TEXT, "This is my Meme");
        getContext().startActivity(Intent.createChooser(share, "Share Your Meme!"));
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_OK && requestCode == PICK_IMAGE) {
            imageUri = Objects.requireNonNull(data).getData();
            imageView.setImageURI(imageUri);
            memeViewModel.setSharedId(imageUri.getLastPathSegment());
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        LocalBroadcastManager.getInstance(Objects.requireNonNull(getActivity())).registerReceiver(addListener, new IntentFilter("ADD_ACTION"));
        LocalBroadcastManager.getInstance(Objects.requireNonNull(getActivity())).registerReceiver(saveListener, new IntentFilter("SAVE_ACTION"));
        LocalBroadcastManager.getInstance(Objects.requireNonNull(getActivity())).registerReceiver(shareListener, new IntentFilter("SHARE_ACTION"));
    }

    private BroadcastReceiver addListener = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            selectedImage();
        }
    };

    private BroadcastReceiver saveListener = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            float height = getBitmap(imageView).getHeight();
            float width = getBitmap(imageView).getWidth();

            if ((height <= 600) || (width <= 600)) {
                saveMeme(screenshotMeme());
                Toast.makeText(getContext(), "screenshotMeme() method was called", Toast.LENGTH_SHORT).show();
            } else {
                saveMeme(drawMeme(getBitmap(imageView)));
                Toast.makeText(getContext(), "drawMeme() method was called", Toast.LENGTH_SHORT).show();
            }
        }
    };

    private BroadcastReceiver shareListener = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            float height = getBitmap(imageView).getHeight();
            float width = getBitmap(imageView).getWidth();

            if ((height <= 600) || (width <= 600)) {
                shareMeme(screenshotMeme());
                Toast.makeText(getContext(), "screenshotMeme() method was called", Toast.LENGTH_SHORT).show();
            } else {
                shareMeme(drawMeme(getBitmap(imageView)));
                Toast.makeText(getContext(), "drawMeme() method was called", Toast.LENGTH_SHORT).show();
            }
        }
    };

    @Override
    public void onPause() {
        super.onPause();
        LocalBroadcastManager.getInstance(Objects.requireNonNull(getActivity())).unregisterReceiver(addListener);
        LocalBroadcastManager.getInstance(Objects.requireNonNull(getActivity())).unregisterReceiver(saveListener);
        LocalBroadcastManager.getInstance(Objects.requireNonNull(getActivity())).unregisterReceiver(shareListener);
    }
}
1个回答

1
问题:因为在switch-case块中,您没有返回或放置break语句,所以每当单击菜单项时,它将执行switch-case中的所有语句。 解决方案:在每个case中放置return true来表示您希望在单击菜单项时消耗该事件。
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()){
        case R.id.add_image:
            localBroadcastManager.sendBroadcast(addImageIntent);
            return true;
        case R.id.save_meme:
            localBroadcastManager.sendBroadcast(saveIntent);
            return true;
        case R.id.share_meme:
            localBroadcastManager.sendBroadcast(shareIntent);
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

或者在每个case语句中使用break语句,然后在方法末尾返回true。

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()){
        case R.id.add_image:
            localBroadcastManager.sendBroadcast(addImageIntent);
            break;
        case R.id.save_meme:
            localBroadcastManager.sendBroadcast(saveIntent);
            break;
        case R.id.share_meme:
            localBroadcastManager.sendBroadcast(shareIntent);
            break;
        default:
            return super.onOptionsItemSelected(item);
    }

    return true;
}

1
如果您在菜单项被点击时消耗事件,则使用return true。如果使用break,则它只是退出switch-case,之后必须返回一个布尔值来指示是否消耗了单击事件。 - Son Truong
啊,我明白了。非常感谢你。我已经点赞并接受了你的答案。如果你认为这是一个很好的问题,你能给我一个赞吗? - Andros Adrianopolos
1
@AndrosAdrianopolos 很高兴听到这个好消息,愉快地编程吧 :) - Son Truong
谢谢。另外,你是否知道如何在不将位图保存到设备的情况下在互联网上共享位图?我正在使用此代码String path = MediaStore.Images.Media.insertImage(Objects.requireNonNull(getContext()).getContentResolver(), bitmap, "Meme", null);shareMeme() 方法中的 Uri 对象,但它会将位图保存在我的设备上,而我只想分享它。 - Andros Adrianopolos
我该如何通过编程从存储中删除图像? - Andros Adrianopolos
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接