Commonsware CWAC 切换片段

Posted

技术标签:

【中文标题】Commonsware CWAC 切换片段【英文标题】:Commonsware CWAC switching fragment 【发布时间】:2014-11-17 17:06:02 【问题描述】:

我正在尝试实现 Commonsware CWAC-Camera,但在将其合并到现有片段中时遇到了问题。

我遇到了无法使用 .add 或 .replace 的问题,它希望我将 CameraFragment 更改为 Fragment。

错误:

FragmentTransaction类型中的add(int, Fragment, String)方法不适用于参数(int, CameraFragment, String)

<uses-sdk
    android:minSdkVersion="13"
    android:targetSdkVersion="21" />


 import java.io.File;
 import java.text.SimpleDateFormat;
 import java.util.Date;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageButton;

import com.commonsware.cwac.camera.CameraFragment;




public void takePicture() 

    CameraFragment f = new CameraFragment();
    getFragmentManager().beginTransaction()
            .add(R.id.contentFragment, f, TAG_CAMERA_FRAGMENT)
            .commit();

以前有人经历过吗?这是整个片段。

public class FeedActivity extends Fragment implements OnClickListener 

    ImageButton btnCamera, btnGallery;
    private final String TAG_CAMERA_FRAGMENT = "camera_fragment";

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.activity_feed, container, false);

        btnCamera = (ImageButton) view.findViewById(R.id.btn_Camera);
        btnCamera.setOnClickListener(this);
        btnGallery = (ImageButton) view.findViewById(R.id.btn_Gallery);
        btnGallery.setOnClickListener(this);

        return view;
    

    @Override
    public void onClick(View v) 
        // TODO Auto-generated method stub
        switch (v.getId()) 

        case R.id.btn_Camera:
        Log.e("CAMERA", "CAMERA BUTTON PRESSED");
            //takePicture();
            break;

        case R.id.btn_Gallery:
            Log.e("Gallery", "GALLERY BUTTON PRESSED");
            break;

        

    

    public void takePicture() 

        CameraFragment f = new CameraFragment();
        getFragmentManager().beginTransaction()
                .add(R.id.contentFragment, f, TAG_CAMERA_FRAGMENT)
                .commit();
    

【问题讨论】:

“我不能使用 .add 或 .replace,它要我将 CameraFragment 更改为 Fragment”——我不知道你的意思。请提供确切的消息并指出是什么给了你消息(IDE?LogCat?别的东西?)如果我不得不猜测,你有错误的导入,并试图将片段反向端口与本机 API 级别 11+ 片段混合,但这只是猜测。 FragmentTransaction类型中的add(int, Fragment, String)方法不适用于参数(int, CameraFragment, String) 我刚刚包含了错误。快速修复阅读“将 f 更改为片段”。我很抱歉。 请编辑您的问题以粘贴到此 Java 源文件的 import 语句的完整列表中。我的猜测是正确的,您正在将一些片段反向移植类与 API 级别 11+ 片段类混合,但没有导入,我无法准确告诉您要更改什么。 【参考方案1】:
import android.support.v4.app.Fragment;

和:

import com.commonsware.cwac.camera.CameraFragment;

不兼容。您需要决定是要使用 Android 支持包中的片段反向移植,还是要使用本机 API 级别 11+ 片段。并且您需要修改整个活动以支持您的选择(例如,如果您使用反向端口,则从 FragmentActivity 继承)。

如果你想使用 backport,你需要使用 camera-v9 库并导入 com.commonsware.cwac.camera.acl.CameraFragment,尽管这也使用了 ActionBarSherlock。如果您想要片段的反向移植而不是 ActionBarSherlock,则需要 fork 我的 CameraFragment 实现之一以支持该组合。

【讨论】:

非常有帮助。谢谢。【参考方案2】:

问题

我想向您展示我解决CameraFragment 不兼容问题的方法。我的应用程序使用 V4 支持库(不知何故我不知道为什么)但没有 ActionBarSherlock。因为我的目标平台是V11及以上(是的,不支持2.3及以下)。

com.commonsware.cwac.camera.CameraFragment -> 与 V4 支持库不兼容,因此与我们的 V4 FragmentActivity 和其他 Fragment 不兼容。

com.commonsware.cwac.camera.acl.CameraFragment -> 无法使用,因为我没有 ActionBarSherlock。

通用解决方案

通常,应用程序会有很多片段,其中一些带有列表或网格。它们都有一些共同的功能。我们可能会使用静态 utils 类,但它可能会产生比解决的问题更多的问题。例如,它需要在函数调用中传递this 片段指针。最后我们有这些:

java.lang.Object
↳ android.support.v4.app.Fragment
  ↳ com.example.app.BaseFragment           <- with common functions

java.lang.Object
↳ android.app.Fragment
  ↳ android.app.ListFragment
    ↳ com.example.app.BaseListFragment     <- with common functions

java.lang.Object
↳ android.app.Fragment
  ↳ com.commonsware.cwac.camera.CameraFragment
    ↳ com.example.app.BaseCameraFragment   <- with common functions

问题

中间类 Fragment 可以从不同的 Fragment 扩展:原始或 V4 支持库。 在这些 Base...Fragment 类中有多个通用函数的副本。维护困难且浪费时间。

但是,我注意到我们从以下片段扩展而来的一些东西:

    它们完成得很好,而且不太可能改变。 它们大多是开源的。 他们通常不会关心他们的父母是原创还是 V4 支持 - 他们自己工作。

解决方案

因此,我们可以(a)更改它们的父类,或(b)克隆它们并从我们喜欢的任何片段扩展,而不是从它们扩展:

java.lang.Object
↳ android.support.v4.app.Fragment
  ↳ com.example.app.BaseFragment           <- with common functions
    ↳ com.example.app.BaseListFragment     
      // with content from android.app.ListFragment
    ↳ com.example.app.BaseCameraFragment
      // with content from com.commonsware.cwac.camera.CameraFragment

(请注意,我们仍然必须遵守适用的 GNU 许可证)

通常,我不想更改他们的源代码,因此我可以在可用时轻松更新到最新版本。所以,我会将原件保留在应用程序中并使用方法b。唯一的工作是将他们的版本与我的克隆进行比较。

好处

    维护一个具有常用功能的片段。 解决基类型不兼容问题。 轻松更改基基片段类型。 (对于 CWAC)我可以避免需要 ActionBarSherlock 的 camera-v9,并且我的所有片段都从 v4 片段扩展。

享受~

【讨论】:

哦,关于为什么我使用 v4 片段,即使最小目标是 Android 4.0+:有一天,我的队友告诉我,在某些早期版本(例如 4.0)中,它们的内置存在问题-在片段中。使用 v4 支持库更明智。这样应用程序将使用 Fragment 和 FragmentActivity 的错误修复版本。如果我错了纠正我。因为我认为使用 V4 库没有什么坏处,所以......

以上是关于Commonsware CWAC 切换片段的主要内容,如果未能解决你的问题,请参考以下文章

在Android Studio片段之间切换时地图片段不隐藏

以编程方式切换片段

切换片段时导航重置

如何在切换片段时停止 AsyncTask?

如何在 Kotlin 片段内的按钮之间切换片段?

片段不使用 FragmentContainerView 切换