TextureView in a Fragment never calls onSurfaceTextureAvailable - android

I've seen lots of examples using TextureView in a main Activity but I'm trying to put it into a Fragment.
I've created the simplest example possible and its onCreateView is being called, onActivityCreated as well but onSurfaceTextureAvailable isn't being called after passing back the TextureView.
What am I missing ?
Thanks
G
public class FullscreenActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fullscreen);
}
}
public class TextureViewFragment extends Fragment
implements TextureView.SurfaceTextureListener {
private TextureView mTextureView;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mTextureView = new TextureView(getActivity());
mTextureView.setSurfaceTextureListener(this);
mTextureView.setOpaque(false);
return mTextureView;
}
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
// TODO Auto-generated method stub
return false;
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width,
int height) {
// TODO Auto-generated method stub
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
// TODO Auto-generated method stub
}
}
activity_fullscreen.xml:
<FrameLayout 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"
android:background="#0099cc"
tools:context=".FullscreenActivity" >
<fragment class="com.example.test.TextureViewFragment"
android:id="#+id/graphTextureView"
android:layout_width="0px" android:layout_height="match_parent" />
</FrameLayout>

This is because the TextureView must have a nonzero size and be visible. Based on the comment, the layout_width was set to 0px. Change that to a nonzero value.
(Old question but posting answer for posterity)

You should add 'android:hardwareAccelerated=true' to your AndroidManifest.xml.
TextureView needs hardware acceleration.

Your TextureView should be in a layout xml file. Instead of using new to instantiate it you should get it using something like this:
View view = inflater.inflate(R.layout.layout_video, container, false);
mTextureView = (TextureView) view.findViewById(R.id.video_texture_view);
Then in your layout_video.xml file you need a TextureView with id video_texture_view

Related

Use YoutubePlayerView on fragment section

I found some similar situation, like this and this, but none of then solved my problem.
I have wanna have a screen with youtube video and some text information like this:
I'm using a activity and a fragment, both with base class that extended YouTubeBaseActivity and YouTubePlayerFragment.
But when I'm trying to open the fragment it show a npe but it don't show where. Since I'm getting the layout and view right, I don't now what is going on.
Hope that it don't get downvotes because is a npe question, but is different from usual, this API call don't show me where the NPE happen and I saw the other people has problems like this
Obs: I'm using this extend base concept because more places will have this videos behaviour and I'm trying to avoid code repeat.
Logcat
XML
<android.support.constraint.ConstraintLayout
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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".screens.mine.fragments.MineStepsFragment">
<com.google.android.youtube.player.YouTubePlayerView
android:id="#+id/mine_steps_youtube_player"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/background_white"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
</com.google.android.youtube.player.YouTubePlayerView>
</android.support.constraint.ConstraintLayout>
Activity
public class MineAccidentActivity extends BaseYoutubeActivity {
#Override
protected void initializeActionBar() {
actionbarLeftBtn.setVisibility(View.VISIBLE);
actionbarTitle.setVisibility(View.VISIBLE);
}
#Override
protected int getActionbarTitle() {
return R.string.mine_accident;
}
#Override
protected int getContentView() {
return R.layout.mine_accident_activity;
}
#Override
protected void assignViews() {
MineAccidentController.getInstance().attachToActivity(this, R.id.mine_container);
}
#Override
protected void prepareViews() {}
/////////////////// BACK ////////////////////
#Override
public void onBackPressed() {
if (!MineAccidentController.getInstance().isFirstFragmentShown()) {
MineAccidentController.getInstance().showPreviousFragment();
} else {
super.onBackPressed();
}
}
/////////////////// LIFE CYCLE ////////////////////
#Override
protected void onDestroy() {
MineAccidentController.getInstance().onDestroy();
super.onDestroy();
}
}
Fragment Controller
public class MineAccidentController extends BaseYoutubeController {
private String accidentType;
#Override
protected ArrayList<android.app.Fragment> initFragments() {
ArrayList<android.app.Fragment> fragments = new ArrayList<>();
fragments.add(new MineStepsFragment());
return fragments;
}
//create Class
public static MineAccidentController getInstance() {
if (null == instance) {
synchronized (MineAccidentController.class) {
if (null == instance) {
setInstance(new MineAccidentController());
}
}
}
return (MineAccidentController) instance;
}
public String getAccidentType() {
return accidentType;
}
public void setAccidentType(String accidentType) {
this.accidentType = accidentType;
}
}
Fragment
public class MineStepsFragment extends BaseYoutubeFragment {
//Not in Layout
private String videoUrl;
////////////// IMPLEMENT_METHODS //////////////
#Override
protected int getFragmentContentView() {
return R.layout.mine_steps_fragment;
}
#Override
protected int getYoutubePlayerView() {
return R.id.mine_steps_youtube_player;
}
#Override
protected void assignViews() {
}
#Override
protected void prepareViews() {
}
#Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer, boolean wasRestored) {
if(!wasRestored){
checkType();
youTubePlayer.cueVideo(videoUrl);
}
}
#Override
public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) {
showErrorToast(getActivity(), R.string.error_initialize_video);
}
////////////// FUNCTIONS //////////////
private void checkType() {
if(MineAccidentController.getInstance().getAccidentType().equals(Parameters.ACCIDENT_PERSONAL)){
videoUrl = Properties.MINE_PERSONAL_VIDEO;
}
else {
videoUrl = Properties.MINE_WORK_VIDEO;
}
}
}
Base Fragment
public abstract class BaseYoutubeFragment extends YouTubePlayerFragment implements YouTubePlayer.OnInitializedListener {
protected View fragmentView = null;
protected YouTubePlayerView youTubePlayerView;
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
assignViews();
prepareViews();
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
fragmentView = inflater.inflate(getFragmentContentView(), container, false);
youTubePlayerView = fragmentView.findViewById(getYoutubePlayerView());
youTubePlayerView.initialize(com.can_apps.eva_ngo.properties.Properties.API_KEY, this);
return fragmentView;
}
/////////////////// ABSTRACT METHODS ////////////////////
protected abstract int getFragmentContentView(); //Get Layout R.layout.name_file
protected abstract int getYoutubePlayerView(); //Get Container for YOutube Video
protected abstract void assignViews(); //Used for findById the params
protected abstract void prepareViews(); //Used for start the values of params
/////////////////// SHOW MESSAGES ////////////////////
public void showErrorToast(Context context, final int message) {
Toast toast = Toast.makeText(context, getString(message), Toast.LENGTH_SHORT);
View view = toast.getView();
view.setBackgroundResource(R.color.background_red_transparent);
toast.show();
}
/////////////////// SNACK BAR ////////////////////
public void showSnackBar(final int text) {
Snackbar.make(Objects.requireNonNull(getView()), getString(text), Snackbar.LENGTH_SHORT).show();
}
public void showSnackBar(final int mainTextStringId, final int actionStringId, View.OnClickListener listener) {
Snackbar.make(Objects.requireNonNull(getView()),
getString(mainTextStringId),
Snackbar.LENGTH_LONG)
.setAction(getString(actionStringId), listener).show();
}
}
Looking at the logcat it looks like your YouTubePlayerView is null when you are calling one of its methods.
The YouTube Player API is quite buggy and difficult to use correctly. To solve this problems (and others) I have built an alternative player Android-YouTube-Player, it's open source and you can do whatever you want with it.
In your case, you won't have to meddle with Fragments and transactions, since my YouTubePlayerView is just a regular view and requires no special Fragments or Activities. You can drop it wherever you want.
Hope it could be useful to you as well!

Android OpenGL ES 2: How to use an OpenGL activity as a fragment in the main activity

I am quite new to Android and OpenGL ES. I have to create a GUI in OpenGL and I would like to use it as a Fragment in the main activity. In order to learn how to do this, I tried 2 tutorials - this Fragment tutorial and the Android developer tutorial on OpenGL ES.
But still I don't understand how exactly do I include an OpenGL view in a Fragment. OpenGL doesn't use XML layout files so this process is quite confusing for me. I would like to do something like this: inside the main activity from the Fragment tutorial I want to include a third Fragment with OpenGL. Go easy on me I am a beginner :)
If the developer tutorial is anything to go by, then the following setup would work:
Activity:
public class MainActivity extends FragmentActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportFragmentManager().addOnBackStackChangedListener(new OnBackStackChangedListener()
{
public void onBackStackChanged()
{
int backCount = getSupportFragmentManager().getBackStackEntryCount();
if (backCount == 0)
{
finish();
}
}
});
if (savedInstanceState == null)
{
getSupportFragmentManager().beginTransaction().add(R.id.main_container, new OpenGLFragment()).addToBackStack(null).commit();
}
}
}
Activity XML (activity_main.xml):
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Fragment:
public class OpenGLFragment extends Fragment
{
private GLSurfaceView mGLView;
public OpenGLFragment()
{
super();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
mGLView = new MyGLSurfaceView(this.getActivity()); //I believe you may also use getActivity().getApplicationContext();
return mGLView;
}
}
And I guess you need to make your own GLSurfaceView as the tutorial says:
class MyGLSurfaceView extends GLSurfaceView {
public MyGLSurfaceView(Context context){
super(context);
setEGLContextClientVersion(2);
// Set the Renderer for drawing on the GLSurfaceView
setRenderer(new MyRenderer());
}
}
And as the tutorial says, make your renderer:
public class MyGLRenderer implements GLSurfaceView.Renderer {
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
// Set the background frame color
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
public void onDrawFrame(GL10 unused) {
// Redraw background color
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
}
public void onSurfaceChanged(GL10 unused, int width, int height) {
GLES20.glViewport(0, 0, width, height);
}
}

What kind of code do i have to put in OnCreate() and when do i have to put it in OnCreateView()?

I am trying to understand when i should use the oncreate method or the oncreateview method.
I am a little bit confused. First i had some code including statements like findViewById() in the OnCreate() method. But it always responded with a null pointer Exception, then someone told me i should put it in the OnCreateView() method. It worked, but i do not understand when and what for code i should put in the OnCreate() or when and what i should put in the OnCreateView(). Could someone please explain this to me.
In my code, the methodology is the following:
ACTIVITY code:
#Override
public void onCreate(Bundle saveInstanceState)
{
super.onCreate(saveInstanceState);
this.setContentView(R.layout.activity_container);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
if (saveInstanceState == null)
{
getSupportFragmentManager().beginTransaction()
.replace(R.id.activity_container_container, new MyFragment()).addToBackStack(null).commit();
}
getSupportFragmentManager().addOnBackStackChangedListener(new OnBackStackChangedListener()
{
public void onBackStackChanged()
{
int backCount = getSupportFragmentManager().getBackStackEntryCount();
if (backCount == 0)
{
finish();
}
}
});
}
#Override
public void myInterface()
{
System.out.println("Do stuff;");
}
FRAGMENT code:
private int titleId;
private Button placeholderButton;
private MyInterface activity_myInterface;
public MyFragment()
{
super();
this.titleId = R.string.my_actionbar_title;
}
#Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
try
{
activity_myInterface = (MyInterface)activity;
}
catch(ClassCastException e)
{
Log.e(this.getClass().getSimpleName(), "MyInterface interface needs to be implemented by Activity.", e);
throw e;
}
}
//this is an interface defined by me
#Override
public int getActionBarTitleId()
{
return titleId;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_myfragment, container, false);
placeholderButton = (Button)view.findViewById(R.id.myfragment_placeholderbtn);
placeholderButton.setOnClickListener(this);
return view;
}
#Override
public void onClick(View v)
{
if(v == placeholderButton)
{
System.out.println("Do more stuff");
}
}
Where R.layout.activity_container is:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout
android:id="#+id/activity_container_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
This way the Activity is responsible for containing the Fragment (and this fragment is created in onCreate()) and the Fragment is responsible for the display of UI and the event handling. You can have more than one fragment on an Activity, though, that's what they primarily were designed for.
If you are using an Activity, then you can just stay away from the onCreateView.
Just stick to the default activity lifecycle:
The layout (content) is inflated (created) at the onCreate method.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_book);
}
Then once it has been inflated you are ready to use it and manipulate views that belong to it.
findViewById() returned null for you because the layout was not ready to be used and that's because it was not yet inflated. You can use findViewById() after setContentView() in onCreate.
findViewById() is a method that can be pretty hard on the performance (if called many times), so you should get all the views you need in onCreate and save them to an instance variable like:
TextView textView1, textView2;
Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_book);
textView1 = findViewById(R.id.textview1);
textView2 = findViewById(R.id.textview2);
...
}
And use them from onStart:
#Override
protected void onStart() {
super.onStart();
if (textView1 != null) textView1.setText("myText");
if (textView2 != null) textView2.setText("some other text");
}

Video is not pausing in fragment ViewPager

I am using View Pager with fragment to showing image and video, I am able to show image and video properly but I have problem, when I swipe for video, then video is playing, but I swipe next or previous then video is still playing on just next or previous screen but when I move two slide next or previous then video is being stop, but why not on next or previous slide.
I search it more but I did not get any solution, any help will be appreciable.
Thanks in advance.
Here is my code:
This is Fragment Class
public class ContentFragment extends Fragment {
private final String imageResourceId;
private String type;
public ContentFragment(String imageResourceId,String type) {
System.out.println("Path In cons="+imageResourceId+"and type is="+type);
this.imageResourceId = imageResourceId;
this.type= type;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e("Test", "hello");
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.content_layout, container, false);
TouchImageView imageView = (TouchImageView) view.findViewById(R.id.touchImage);
imageView.setImageResource(R.id.touchImage);
imageView.setMaxZoom(10f);
VideoView videoView =(VideoView) view.findViewById(R.id.videoView1);
if(type.equals("image")) {
imageView.invalidate();
imageView.setVisibility(View.VISIBLE);
videoView.setVisibility(View.GONE);
try {
System.out.println("IN Content Fragment"+imageResourceId.toString());
Bitmap bmp = BitmapFactory.decodeFile(imageResourceId.toString());
imageView.setImageBitmap(bmp);
} catch(Exception e) {
System.out.println("Error Of image File"+e);
}
} else
try {
if(type.equals("video")){
videoView.invalidate();
videoView.setVisibility(View.VISIBLE);
imageView.setVisibility(View.GONE);
String path = imageResourceId.toString();
videoView.setVideoURI(Uri.parse(path));
videoView.setMediaController(new MediaController(getActivity()));
videoView.setFocusable(true);
videoView.start();
}
} catch(Exception e) {
e.printStackTrace();
}
return view;
}
}
This is pager adapter activity
public class MediaActivity extends FragmentActivity {
private MyAdapter mAdapter;
private ViewPager mPager;
public ArrayList<Content> contentList;
Context context;
LinearLayout numberOfPageLayout;
SharedPreferences sharedPreferences;
Handler progressHandler;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_media);
context=(Context) getApplicationContext();
mPager = (ViewPager) findViewById(R.id.pager);
progressHandler = new Handler();
contentList=new ArrayList<Content>();
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
contentList=new ContentDBAdapter(context).getAllContent();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
mAdapter = new MyAdapter(getSupportFragmentManager(),contentList);
mPager.setAdapter(mAdapter);
}
}.execute();
mPager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int arg0) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
});
}
public static class MyAdapter extends FragmentPagerAdapter {
ArrayList <Content>contList=new ArrayList<Content>();
public MyAdapter(FragmentManager fm,ArrayList<Content> cont) {
super(fm);
this.contList=cont;
}
#Override
public int getCount() {
totalPage=contList.size();
return contList.size();
}
#Override
public Fragment getItem(int position) {
Content con=contList.get(position);
return new ContentFragment(con.getPath(),con.getType());
}
}
}
It is because ViewPager keeps offscreen fragments started. For instance you have a fragment visible to the user. ViewPager will try to keep the previous fragment (on the left side) and the next fragment (on the right side) started. This allows ViewPager performing smooth sliding when user decides to change the page, because the next and the previous pages are already prepared.
In your case the video player is not visible (offscreen), but ViewPager keeps it started as due to the behaviour described above. You can use setOffscreenPageLimit() method to change this behaviour. If you set page limit to 0, then offscreen fragments will be paused immediately. Unfortunately they will not only be paused, but stopped and detached from the activity too. This means when you return back to your fragment, it will recreate the whole layout anew. That's why you can try to override either Fragment.setUserVisibleHint() or Fragment.onHiddenChanged() and execute your pause/play logic there. ViewPager will update hidden state of a fragment depending on whether the fragment is actually visible to user or not.
Hope this helps.
You have to override setUserVisibleHint method in a fragment where u play video.
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (this.isVisible())
{
if (!isVisibleToUser) // If we are becoming invisible, then...
{
//pause or stop video
}
if (isVisibleToUser)
{
//play your video
}
}
}
I handle the problem like this:
boolean isVisible = false;
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
isVisible = isVisibleToUser;
if(player!=null)
player.pause();
super.setUserVisibleHint(isVisibleToUser);
}
then in onCreateView method:
SimpleExoPlayer player;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_screen_slide_page, container, false);
PlayerView playerView = v.findViewById(R.id.playerView);
playerView.getLayoutParams().width = ListPager.widthPixels;
playerView.getLayoutParams().height = ListPager.widthPixels;
if(player!=null)
player.release();
player = new SimpleExoPlayer.Builder(App.applicationContext).build();
playerView.setPlayer(player);
MediaItem mediaItem = MediaItem.fromUri(url);
player.setMediaItem(mediaItem);
player.prepare();
//---------The following code is important because if you remove the following if
// then if the next page is displaying, android will automatically initiate the
// previous and the next page, and the player will start playing :|
if(isVisible)
player.play();
}

rendaring issue with surfaceview in viewflipper?

i am drawing a piechart by extending surfaceview to PieChart Class. now i am creating 2 objects for Piechart and adding to a VieWFlipper to swipe between those charts. now my problem is 2nd Piechart is not visible to the user if user swipes to 2nd view. but all the 2nd pies functionality is working. i am thinking like its refresh problem of the surfaceview.
any help on this will be appreciable. the following is my PieChart class.
class MyPieChart extends SurfaceView implements SurfaceHolder.Callback {
#Override
public void onDraw(Canvas canvas) {
if (hasData) {
resetColor();
try {
canvas.drawColor(getResources().getColor(R.color.graphbg_color));
graphDraw(canvas);
} catch (ValicException ex) {
}
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Log.i("PieChart", "surfaceChanged");
}
public int callCount = 0;
#Override
public void surfaceCreated(SurfaceHolder holder) {
if ((callCount++) % 2 == 0) {
callCount = 1;
try {
Log.i("PieChart", "surfaceCreated");
mChartThread = new ChartThread(getHolder(), this);
mChartThread.setRunning(true);
if (!mChartThread.isAlive()) {
mChartThread.start();
}
mFrame = holder.getSurfaceFrame();
mOvalF = new RectF(0, 0, mFrame.right, mFrame.right);
} catch (Exception e) {
// No error message required
}
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.i("PieChart", "surfaceDestroyed");
boolean retry = true;
callCount = 0;
mChartThread.setRunning(false);
while (retry) {
try {
mChartThread.join();
retry = false;
} catch (InterruptedException e) {
// No error message required
}
}
}
}
class ChartThread extends Thread {
private SurfaceHolder mSurfaceHolder;
private PieChart mPieChart;
private boolean mRefresh = false;
public ChartThread(SurfaceHolder surfaceHolder, PieChart pieChart) {
// Log.i("ChartThread", "ChartThread");
mSurfaceHolder = surfaceHolder;
mPieChart = pieChart;
}
public void setRunning(boolean Refresh) {
// Log.i("ChartThread", "setRunning : " + Refresh);
mRefresh = Refresh;
}
#Override
public void run() {
Canvas c;
// Log.i("ChartThread", "run : " + mRefresh);
while (mRefresh) {
c = null;
try {
c = mSurfaceHolder.lockCanvas(mPieChart.mFrame);
// c.drawColor(0xFFebf3f5);
synchronized (mSurfaceHolder) {
mPieChart.onDraw(c);
}
} catch (Exception ex) {
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
here is my flipper.xml
<ViewFlipper
android:id="#+id/flipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout android:id="#+id/pie1"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<LinearLayout android:id="#+id/pie2"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
and i here is my activity
public class ViewFlipperActivity extends Activity {
Button b1;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b1 = (Button)findViewById(R.id.submit1);
b1.setOnClickListener(new View.OnClickListener() {
ViewFlipper vflipper=(ViewFlipper)findViewById(R.id.flipper);
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
vflipper.showNext();
}
});
}
and i am dding the piecharts to Pie1 and Pie2 LinearLayouts in the Flipper.
both the pie's are created and pasted on to the Pie Layouts. now if i move to the 2nd view in the flipper Pie1 is showing instead of pie2 and all other data and functionality which i am getting is related to Pie2. my doubt is Pie2 is rendering and hidden under Pie1. can any one help me on this with some solution.
i got a break through for this issue. which caused another issue with the following changes.
in flipper.xml replaced LinearLayout i place of view flipper.
<LinearLayout
android:id="#+id/flipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout android:id="#+id/pie1"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout >
and in ViewFlipperActivity
public class ViewFlipperActivity extends Activity {
Button b1;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b1 = (Button)findViewById(R.id.submit1);
b1.setOnClickListener(new View.OnClickListener() {
LinearLayout vflipper=(LinearLayout)findViewById(R.id.flipper);
LinearLayout pie1=(LinearLayout)findViewById(R.id.pie1);
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
vflipper.setAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_in));
pie1.removeAllViews();
pie1.addView(PieChart/SurfaceView);
}
});
}
with the animation and is working fine and piechart is getting changed on the view. but block rect is getting visible from the surfaceview for a sec when swiping between piecharts. can some one help me on this issue.
SurfaceView is not going to work properly inside a ViewFlipper as it cannot be animated correctly. This is why Android 4.0 introduces a new widget called TextureView that solves this problem.
here main problem is SurfaceView cannot be animated. that's why neither ViewFlipper nor Layout Animation cannot be applied for SurfaceView.

Categories

Resources