android - Using a ViewPager over a CameraPreview -
i've been trying create camera preview displays view pager several transparent images on preview. but, i'm getting error:
05-10 03:31:23.614: e/androidruntime(674): fatal exception: main 05-10 03:31:23.614: e/androidruntime(674): java.lang.nullpointerexception 05-10 03:31:23.614: e/androidruntime(674): @ com.android.gs1.mainactivity$camerapreview.surfacecreated(mainactivity.java:102) 05-10 03:31:23.614: e/androidruntime(674): @ android.view.surfaceview.updatewindow(surfaceview.java:562) 05-10 03:31:23.614: e/androidruntime(674): @ android.view.surfaceview.access$000(surfaceview.java:82) 05-10 03:31:23.614: e/androidruntime(674): @ android.view.surfaceview$3.onpredraw(surfaceview.java:171) 05-10 03:31:23.614: e/androidruntime(674): @ android.view.viewtreeobserver.dispatchonpredraw(viewtreeobserver.java:590) 05-10 03:31:23.614: e/androidruntime(674): @ android.view.viewrootimpl.performtraversals(viewrootimpl.java:1596) 05-10 03:31:23.614: e/androidruntime(674): @ android.view.viewrootimpl.handlemessage(viewrootimpl.java:2418) 05-10 03:31:23.614: e/androidruntime(674): @ android.os.handler.dispatchmessage(handler.java:99) 05-10 03:31:23.614: e/androidruntime(674): @ android.os.looper.loop(looper.java:137) 05-10 03:31:23.614: e/androidruntime(674): @ android.app.activitythread.main(activitythread.java:4340) 05-10 03:31:23.614: e/androidruntime(674): @ java.lang.reflect.method.invokenative(native method) 05-10 03:31:23.614: e/androidruntime(674): @ java.lang.reflect.method.invoke(method.java:511) 05-10 03:31:23.614: e/androidruntime(674): @ com.android.internal.os.zygoteinit$methodandargscaller.run(zygoteinit.java:784) 05-10 03:31:23.614: e/androidruntime(674): @ com.android.internal.os.zygoteinit.main(zygoteinit.java:551) 05-10 03:31:23.614: e/androidruntime(674): @ dalvik.system.nativestart.main(native method)
here code:
package com.android.gs1; import java.io.ioexception; import android.os.bundle; import android.os.parcelable; import android.app.activity; import android.content.context; import android.hardware.camera; import android.support.v4.view.pageradapter; import android.support.v4.view.viewpager; import android.util.log; import android.view.layoutinflater; import android.view.surfaceholder; import android.view.surfaceview; import android.view.view; import android.view.viewgroup; import android.widget.linearlayout; import android.widget.toast; public class mainactivity extends activity { viewpager vp; camera mcamera; surfaceholder mholder; static int j; private vpadapter myadapter; camerapreview preview; public static void passpagenumber(int i){ j = i; } @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); toast.maketext(getapplicationcontext(), "swipe left or right select option", toast.length_long).show(); vp = (viewpager) findviewbyid(r.id.viewpager); myadapter = new vpadapter(); preview = new camerapreview(getapplicationcontext(), mcamera); ((linearlayout) findviewbyid(r.id.preview)).addview(preview); vp.setadapter(myadapter); } private class camerapreview extends surfaceview implements surfaceholder.callback{ private final string tag = null; public camerapreview(context context, camera camera) { super(context); // todo auto-generated constructor stub mcamera = camera; // install surfaceholder.callback notified when // underlying surface created , destroyed. mholder = getholder(); mholder.addcallback(this); // deprecated setting, required on android versions prior 3.0 // mholder.settype(surfaceholder.surface_type_push_buffers); } @override public void surfacechanged(surfaceholder holder, int format, int width, int height) { // todo auto-generated method stub if (mholder.getsurface() == null){ // preview surface not exist return; } // stop preview before making changes try { mcamera.stoppreview(); } catch (exception e){ // ignore: tried stop non-existent preview } // set preview size , make resize, rotate or // reformatting changes here // start preview new settings try { mcamera.setpreviewdisplay(mholder); mcamera.startpreview(); } catch (exception e){ log.d(tag, "error starting camera preview: " + e.getmessage()); } } @override public void surfacecreated(surfaceholder holder) { // todo auto-generated method stub try { mcamera = camera.open(); mcamera.setpreviewdisplay(holder); mcamera.startpreview(); } catch (ioexception e) { log.d(tag, "error setting camera preview: " + e.getmessage()); } } @override public void surfacedestroyed(surfaceholder holder) { // todo auto-generated method stub } } private class vpadapter extends pageradapter{ @override public int getcount() { // todo auto-generated method stub return 5; } @override public boolean isviewfromobject(view view, object object) { // todo auto-generated method stub return view == ((linearlayout)object); } @override public void destroyitem(viewgroup container, int position, object object) { // todo auto-generated method stub ((viewpager)container).removeview((linearlayout)object); } @override public void finishupdate(viewgroup container) { // todo auto-generated method stub } @override public object instantiateitem(view container, int position) { // todo auto-generated method stub layoutinflater inflater = (layoutinflater)container.getcontext().getsystemservice(context.layout_inflater_service); view v = null; switch(position){ case 0: v = inflater.inflate(r.layout.first, null); break; case 1: v = inflater.inflate(r.layout.second, null); break; case 2: v = inflater.inflate(r.layout.third, null); break; case 3: v = inflater.inflate(r.layout.fourth, null); break; case 4: v = inflater.inflate(r.layout.fifth, null); break; } ((viewpager)container).addview(v, 0); return v; } @override public void startupdate(viewgroup container) { // todo auto-generated method stub } @override public parcelable savestate() { // todo auto-generated method stub return null; } } }
here xml
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".mainactivity" android:background="#545454" > <android.support.v4.view.viewpager android:id="@+android:id/viewpager" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="0.49" /> <linearlayout android:id="@+id/preview" android:layout_width="wrap_content" android:layout_height="wrap_content"> </linearlayout> </linearlayout>
there 5 more xml viewpager. of them this, different name , ids.
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <imageview android:id="@+id/image1" android:layout_width="match_parent" android:layout_height="wrap_content" android:adjustviewbounds="false" android:contentdescription="@string/description_image_1" android:scaletype="fitxy" android:src="@drawable/first" /> </linearlayout>
thank much
edit: asked me final working version of code. here is:
public class mainactivity extends activity { viewpager vp; vpadapter myadapter; camera camera = null; surfaceholder previewholder = null; private surfaceview preview = null; private boolean inpreview = false; private boolean cameraconfigured = false; public static string[] arrayurl; public static boolean urlspassed; private view mcontentview; private view mloadingview; private int mshortanimationduration; @suppresswarnings("deprecation") @suppresslint("newapi") @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); requestwindowfeature(window.feature_no_title); setcontentview(r.layout.activity_main); toast.maketext(getapplicationcontext(), "swipe left or right select option", toast.length_short).show(); //new code mcontentview = findviewbyid(r.id.content); mloadingview = findviewbyid(r.id.loading_spinner); mcontentview.setvisibility(view.gone); mshortanimationduration = getresources().getinteger( android.r.integer.config_shortanimtime); //new code preview=(surfaceview)findviewbyid(r.id.preview); preview.setzorderontop(false); previewholder=preview.getholder(); previewholder.addcallback(surfacecallback); previewholder.settype(surfaceholder.surface_type_push_buffers); } private void crossfade() { // set content view 0% opacity visible, visible // (but transparent) during animation. mcontentview.setalpha(0f); mcontentview.setvisibility(view.visible); // animate content view 100% opacity, , clear animation // listener set on view. mcontentview.animate() .alpha(1f) .setduration(mshortanimationduration) .setlistener(null); // animate loading view 0% opacity. after animation ends, // set visibility gone optimization step (it won't // participate in layout passes, etc.) mloadingview.animate() .alpha(0f) .setduration(mshortanimationduration) .setlistener(new animatorlisteneradapter() { @override public void onanimationend(animator animation) { mloadingview.setvisibility(view.gone); } }); } public static void assignurl(string[] urls){ arrayurl = urls; } public static void urlspassed(boolean transfer){ urlspassed = transfer; } @override public void onresume() { super.onresume(); camera=camera.open(); } @override public boolean oncreateoptionsmenu(menu menu) { getmenuinflater().inflate(r.menu.main, menu); return true; } @override public void onpause() { if (inpreview) { camera.stoppreview(); } camera.release(); camera=null; inpreview=false; super.onpause(); } private camera.size getbestpreviewsize(int width, int height,camera.parameters parameters) { camera.size result=null; (camera.size size : parameters.getsupportedpreviewsizes()) { if (size.width<=width && size.height<=height) { if (result==null) { result=size; } else { int resultarea=result.width*result.height; int newarea=size.width*size.height; if (newarea>resultarea) { result=size; } } } } return(result); } private void initpreview(int width, int height) { if (camera!=null && previewholder.getsurface()!=null) { try { camera.setpreviewdisplay(previewholder); } catch (throwable t) { log.e("previewdemo-surfacecallback", "exception in setpreviewdisplay()", t); toast .maketext(mainactivity.this, t.getmessage(), toast.length_long) .show(); } if (!cameraconfigured) { camera.parameters parameters=camera.getparameters(); camera.size size=getbestpreviewsize(width, height, parameters); if (size!=null) { parameters.setpreviewsize(size.width, size.height); camera.setparameters(parameters); cameraconfigured=true; } } } } private void startpreview() { if (cameraconfigured && camera!=null) { camera.startpreview(); inpreview=true; crossfade(); if(urlspassed){ myadapter = new vpadapter(this, arrayurl); vp = (viewpager) findviewbyid(r.id.viewpager); vp.setadapter(myadapter); vp.setcurrentitem(0); } } } surfaceholder.callback surfacecallback=new surfaceholder.callback() { @override public void surfacecreated(surfaceholder holder) { // no-op -- wait until surfacechanged() } @override public void surfacechanged(surfaceholder holder, int format, int width,int height) { camera.parameters parameters = camera.getparameters(); parameters.setfocusmode(camera.parameters.focus_mode_auto); camera.setparameters(parameters); initpreview(width, height); startpreview(); camera.autofocus(null); } @override public void surfacedestroyed(surfaceholder holder) { // no-op } }; }
for future people struggling kind of problem. found solution:
first, whatever set in top of preview must placed after surfaceview in layout. instance:
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" android:layout_height="wrap_content" tools:context=".mainactivity" android:background="#ffff"> <android.view.surfaceview android:id="@+id/preview" android:layout_width="4978dp" android:layout_height="5131dp"> </android.view.surfaceview> <android.support.v4.view.viewpager android:id="@+android:id/viewpager" android:layout_width="fill_parent" android:layout_height="fill_parent"/> </relativelayout>
second, in java file, surfaceview must setzorderontop false. instance:
surfaceview preview=(surfaceview)findviewbyid(r.id.preview); preview.setzorderontop(false);
third, set layout on top of camerapreview after calling startpreview function in camera.
that's it.
Comments
Post a Comment