如何在 XML 布局中使用扩展类?
Posted
技术标签:
【中文标题】如何在 XML 布局中使用扩展类?【英文标题】:How do you use an extended class in XML layout? 【发布时间】:2015-10-30 04:58:45 【问题描述】:我为相机预览创建了 SurfaceView 的扩展类。
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback
SurfaceHolder mHolder;
Camera mCamera;
CameraPreview(Context context)
super(context);
mHolder = this.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
public void surfaceCreated(SurfaceHolder holder)
// The Surface has been created, acquire the camera and tell it where
// to draw.
try
mCamera = Camera.open();
mCamera.setPreviewDisplay(holder);
catch (Exception e)
Log.wtf("surfaceCreated", e.toString());
public void surfaceDestroyed(SurfaceHolder holder)
try
mCamera.stopPreview();
mCamera.release();
mCamera = null;
catch (Exception e)
Log.wtf("surfaceDestroyed", e.toString());
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
try
Camera.Parameters parameters = mCamera.getParameters();
// parameters.setPreviewSize(w, h);
// parameters.setPreviewSize(222, 222);
mCamera.setParameters(parameters);
mCamera.startPreview();
catch (Exception e)
Log.wtf("surfaceChanged", e.toString());
在这样的活动中使用时,它可以作为全屏预览:
public class CameraActivity extends Activity
CameraPreview mPreview;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
mPreview = new CameraPreview(this);
setContentView(mPreview);
当我尝试在 XML 布局文件中使用它时,它会给出 ClassNotFoundException。
<CameraPreview class="com.xxxxxx.camera3.CameraPreview"
android:layout_
android:layout_
android:id="@+id/surfaceView"
android:background="#ff404040"
android:layout_gravity="center_horizontal"/>
我需要做什么才能让它工作? 如何在 SurfaceView 中放置相机预览?
【问题讨论】:
【参考方案1】:假设包含新视图的包被称为:com.ranandar.views
在您的 xml 中执行以下操作:
<com.ranandar.views.CameraPreview
android:layout_
android:layout_
android:id="@+id/surfaceView"
android:background="#ff404040"
android:layout_gravity="center_horizontal"/>
这会在 com.ranandar.views 包中查找,找到定义该视图的类并使用它。
您的活动中存在问题。您将内容视图设置为表面视图,这是不对的。
编辑:添加您请求的示例。
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback
SurfaceHolder mHolder;
Camera mCamera;
CameraPreview(Context context)
super(context);
init();
CameraPreview(Context context, AttributeSet attrs)
super(context, attrs);
init();
public void init()
mHolder = this.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
//additionally with all your other code
...
所以我所做的是添加了定义自定义视图所需的构造函数,并在 XML 中使用它。您需要定义额外的构造函数,以便在 XML 中使用它时,将属性集传递给视图。属性集是您声明的各种字段,如 layout_width/height、背景等。否则,如果没有此构造函数,CameraPreview 将无法膨胀,因为传递了属性集而没有构造函数来处理它。双参数构造函数 super(context, attrs) 中的调用使用您定义的属性进行处理。
您可能需要进一步学习的文档:Creating Custom Views
需要为您的 XML 文件创建一个 ViewGroup 类的根视图,如 RelativeLayout、LinearLayout 等...在这种情况下进行框架布局:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_
andorid:layout_>
<com.ranandar.views.CameraPreview
android:id="@+id/camera_preview"
android:layout_
android:layout_
android:id="@+id/surfaceView"
android:background="#ff404040"
android:layout_gravity="center_horizontal"/>
</FrameLayout>
假设这个 xml 文件被称为 activity_main.xml
执行以下操作:
public class CameraActivity extends Activity
CameraPreview mPreview;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestWindowFeature(Window.FEATURE_NO_TITLE);
mPreview = (CameraPreview) findViewById(R.id.camera_preview);
始终确保首先设置内容视图,然后再进行可能调用布局的任何其他操作。这可能对您来说是个问题
【讨论】:
另外,您需要在CameraPreview
上实现两参数构造函数,即采用 Context
和 AttributeSet
的构造函数。
抱歉 Lucas,但这样做会导致 InflateException。上面显示的活动只是一个测试。
你按照常识说的做了吗??
另外,我只是在回答关于如何使用自定义视图的问题:P
我想我不明白如何“实现双参数构造函数”。现在我得到 InflateException 和 NoSuchMethodException。甚至可以向 Java 中的可视化组件添加功能吗?我在 C# 中使用继承毫无问题地做到了这一点。关于如何做到这一点的示例或一些文档将非常有帮助。以上是关于如何在 XML 布局中使用扩展类?的主要内容,如果未能解决你的问题,请参考以下文章
Android在Activity里如何获得另一个xml布局文件的控件
在Android中,如何将数据从类传递到相应的布局/片段文件?