2017-10-05 4 views
0

J'ai un problème où j'ai une vue de surface à l'intérieur d'un pager de vue. Tout va bien jusqu'à ce que j'appuie sur l'un des onglets. Le pager de la vue défile, mais la page de l'écran suivant est écrasée.Surface vue écrasée à l'intérieur de la vue téléavertisseur

enter image description here

enter image description here

Si je quitte l'application et revenir en elle, la deuxième page rendra bien. Ensuite, si je presse pour revenir au premier, il écrase à nouveau. Je ne sais pas du tout quelle partie de la mise en page va mal, et pour autant que je sache, la hauteur réelle de la vue de surface ne change pas, comme lorsque j'utilise la méthode .getHeight() sur la vue de surface retourne toujours la même valeur.

Voici ma classe de pager vue:

public class PendulumViewPager extends ViewPager { 


public PendulumViewPager(Context context) { 
    super(context); 
} 

public PendulumViewPager(Context context, AttributeSet attrs) { 
    super(context, attrs); 
} 

@Override 
public boolean onTouchEvent(MotionEvent ev) { 
    return false; 
} 

@Override 
public boolean onInterceptTouchEvent(MotionEvent ev) { 
    return false; 
} 

Voici le fragment étant ajouté au téléavertisseur de vue:

public class SurfacePanelFragment extends Fragment{ 

private int TYPE = 1; 
private SurfacePanel panel; 
public void setType(int type){ 
    TYPE = type; 
} 

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

    panel = view.findViewById(R.id.canvas); 
    panel.setType(TYPE); 
    return view; 
} 

public void startStopPendulum(ImageButton view){ 
    panel.startStop(view); 
} 

public void stopPendulum(){ 
    panel.stop(); 
} 

@Override 
public void onResume() { 
    if(getUserVisibleHint()) { 
     panel.delayStartThread(); 
     ((MainActivity)getActivity()).getStopButton().setImageDrawable(getContext().getResources().getDrawable(R.drawable.ic_pause_white_48dp)); 
    } 
    super.onResume(); 
} 

@Override 
public void onPause() { 
    panel.terminate(); 
    super.onPause(); 
} 

public void stopRendering(){ 
    panel.stopRendering(); 
} 

public void startRendering(){ 
    panel.startRendering(); 
} 

@Override 
public void setUserVisibleHint(boolean isVisibleToUser) { 
    super.setUserVisibleHint(isVisibleToUser); 
    if(panel != null) { 
     if (isVisibleToUser) { 
      panel.delayStartThread(); 
      ((MainActivity)getActivity()).getStopButton().setImageDrawable(getContext().getResources().getDrawable(R.drawable.ic_pause_white_48dp)); 
      Log.i("WP", String.valueOf(panel.getHeight())); 
     } else { 
      panel.terminate(); 
     } 
    } 
} 

Et voici l'activité principale:

public class MainActivity extends AppCompatActivity { 

private PendulumViewPager pager; 
private ArrayList<SurfacePanelFragment> fragments = new ArrayList<SurfacePanelFragment>(2); 

private ImageButton stopButton; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    Toolbar toolbar = findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 
    getSupportActionBar().setDisplayShowTitleEnabled(false); 

    pager = findViewById(R.id.view_pager); 
    pager.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()) { 
     @Override 
     public Fragment getItem(int position) { 
      SurfacePanelFragment frag = new SurfacePanelFragment(); 
      switch (position) { 
       case 0: 
        frag.setType(SurfacePanel.SINGLE_PENDULUM); 

        fragments.add(0, frag); 
        return frag; 
       case 1: 
        frag.setType(SurfacePanel.DOUBLE_PENDULUM); 
        fragments.add(1, frag); 
        return frag; 
       default: 
        return null; 
      } 
     } 

     @Override 
     public int getCount() { 
      return 2; 
     } 

     @Override 
     public CharSequence getPageTitle(int position) { 
      switch (position){ 
       case 0: return "Single"; 
       case 1: return "Double"; 
       default: return ""; 
      } 
     } 
    }); 

    TabLayout pagerTabs = findViewById(R.id.pager_tabs); 
    pagerTabs.setTabGravity(TabLayout.GRAVITY_FILL); 
    pagerTabs.setupWithViewPager(pager); 

    stopButton = findViewById(R.id.stop_button); 
    stopButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      startStopCurrentPendulum((ImageButton) view); 
     } 
    }); 

    ImageButton helpButton = findViewById(R.id.help_button); 
    helpButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      startHelpActivity(); 
     } 
    }); 
} 

private void startStopCurrentPendulum(ImageButton view) { 
    fragments.get(pager.getCurrentItem()).startStopPendulum(view); 
} 

public ImageButton getStopButton(){ 
    return stopButton; 
} 

private void startHelpActivity(){ 
    Intent intent = new Intent(this, HelpActivity.class); 
    startActivity(intent); 
} 

Voici la classe SurfacePanel

public class SurfacePanel extends SurfaceView implements SurfaceHolder.Callback { 

public static final int SINGLE_PENDULUM = 1; 
public static final int DOUBLE_PENDULUM = 2; 

private int TYPE = 1; 

private PendulumThread _thread; 
private boolean needToStartThread = false; 

private SurfaceHolder holder; 

public SurfacePanel(Context context, AttributeSet attrSet) { 
    super(context, attrSet); 
    SurfaceHolder holder = getHolder(); 
    holder.addCallback(this); 
} 


@Override 
public void surfaceCreated(SurfaceHolder surfaceHolder) { 
    Log.i("WP", String.valueOf(this.getHeight())); 
    this.holder = surfaceHolder; 
    if(needToStartThread){ 
     startThread(); 
     needToStartThread = false; 
    } 
} 

@Override 
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) { 

} 

@Override 
public void surfaceDestroyed(SurfaceHolder surfaceHolder) { 
    if(_thread != null) { 
     try { 
      _thread.terminate(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
    this.holder = null; 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    if (_thread != null) { 
     if (event.getAction() == MotionEvent.ACTION_DOWN) { 
      _thread.click(event); 
     } else if (event.getAction() == MotionEvent.ACTION_MOVE) { 
      _thread.updatePos(event); 
     } else if (event.getAction() == MotionEvent.ACTION_UP) { 
      _thread.unclick(); 
     } 
    } 
    return true; 
} 

public void startStop(ImageView button) { 
    if(_thread != null){ 
     if(_thread.isPRunning()){ 
      button.setImageDrawable(getContext().getResources().getDrawable(R.drawable.ic_play_arrow_white_48dp)); 
      _thread.pStop(); 
     }else{ 
      button.setImageDrawable(getContext().getResources().getDrawable(R.drawable.ic_pause_white_48dp)); 
      _thread.pStart(); 
     } 
    } 
} 

public void start(){ 
    if(_thread != null){ 
     _thread.pStart(); 
    } 
} 

public void stop(){ 
    if(_thread != null){ 
     _thread.pStop(); 
    } 
} 

public void stopRendering(){ 
    if(_thread != null){ 
     Log.i("WP", "A"); 
     _thread.stopRendering(); 
    } 
} 

public void startRendering(){ 
    if(_thread != null){ 
     Log.i("WP", "D"); 
     _thread.startRendering(); 
    } 
} 

public void terminate(){ 
    if(_thread != null){ 
     try { 
      _thread.terminate(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

private void startThread(){ 
    if(_thread == null || !_thread.isAlive()) { 
     switch (TYPE) { 
      case SurfacePanel.SINGLE_PENDULUM: 
       _thread = new SinglePendulumThread(holder, getWidth(), getHeight(), getContext()); 
       _thread.pStart(); 
       _thread.start(); 
       break; 
      case SurfacePanel.DOUBLE_PENDULUM: 
       _thread = new DoublePendulumThread(holder, getWidth(), getHeight(), getContext()); 
       _thread.pStart(); 
       _thread.start(); 
       break; 
      default: 
       _thread = new SinglePendulumThread(holder, getWidth(), getHeight(), getContext()); 
       _thread.pStart(); 
       _thread.start(); 
       break; 
     } 
    } 
} 

public void delayStartThread(){ 
    if(holder == null) { 
     needToStartThread = true; 
    }else{ 
     startThread(); 
    } 
} 

public void setType(int type){ 
    TYPE = type; 
} 

Et voici le fragment de panneau de surface avec la vue du panneau de surface

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:orientation="vertical" android:layout_width="match_parent" 
android:layout_height="match_parent"> 
<com.astarphysics.wikidpendulum.SurfacePanel 
    android:id="@+id/canvas" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:layout_editor_absoluteX="8dp" 
    tools:layout_editor_absoluteY="8dp" /> 
</RelativeLayout> 

C'est le seul fil de pendule

public class SinglePendulumThread extends PendulumThread{ 

private SurfaceHolder holder; 
private Paint paint; 
private int backgroundColor; 
private int width; 
private Context context; 

private boolean clicked = false; 

private static final double g = 9.81; 
private final int RADIUS; 

private int length; 
private double theta = Math.PI/8; 
private double thetaV = 0; 

SinglePendulumThread(SurfaceHolder holder, int width, int height, Context context){ 
    this.holder = holder; 
    this.context = context; 

    int bobColor = context.getResources().getColor(R.color.colorBob); 
    int shadowColor = context.getResources().getColor(R.color.shadowColor); 
    backgroundColor = context.getResources().getColor(R.color.backgroundColor); 
    paint = new Paint(); 
    paint.setColor(bobColor); 
    paint.setShadowLayer(5, -1, 2, shadowColor); 

    this.width = width; 
    RADIUS = dpToPx(20); 
    length = dpToPx(200); 
} 

protected void update(){ 
    if(pRunning && !clicked) { 
     thetaV += (-1 * g * Math.sin(theta))/length; 
     theta += thetaV * (40 * Math.pow(10, -2)); 
    } 
} 

protected void render(){ 
    Canvas canvas = holder.lockCanvas(); 
    canvas.drawColor(backgroundColor); 

    canvas.drawLine(width/2, 0, (float) ((width/2) + (length * Math.sin(theta))), (float) (length * Math.cos(theta)), paint); 
    canvas.drawCircle((int) Math.round((width/2) + (length * Math.sin(theta))), (int) Math.round(length * Math.cos(theta)), RADIUS, paint); 

    holder.unlockCanvasAndPost(canvas); 
} 

@Override 
void click(MotionEvent e) { 
    clicked = true; 
    updatePos(e); 
} 

@Override 
void updatePos(MotionEvent e){ 
    length = (int)Math.round(Math.sqrt((Math.abs(e.getX()-(width/2))*Math.abs(e.getX()-(width/2)))+(e.getY()*e.getY()))); 
    theta = Integer.signum(Math.round((e.getX()-(width/2))))*Math.asin((Math.abs(e.getX()-(width/2))/length)); 
} 

@Override 
void unclick() { 
    this.resetForPStart(); 
    clicked = false; 
} 

private void resetForPStart(){ 
    thetaV = 0; 
} 

private int dpToPx(int dp) { 
    DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); 
    return Math.round(dp * (displayMetrics.xdpi/DisplayMetrics.DENSITY_DEFAULT)); 
} 

et c'est le fil double pendule:

public class DoublePendulumThread extends PendulumThread { 

private SurfaceHolder holder; 
private Paint paint; 
private int backgroundColor; 
private int width; 
private int height; 
private Context context; 

private boolean clicked1 = false; 
private boolean clicked2 = false; 

private final int RADIUS; 
private final double m1 = 3; 
private final double m2 = 3; 
private static final double g = 9.81; 

private double l1; 
private double l2; 

private double[] state = new double[4]; 
private double[] dydt = new double[4]; 
private double[] prev = new double[4]; 
private double[] midpt = new double[4]; 
private static final double h = 0.5; 
private static final double DIMENSION = 4; 
private static final double HALF = h/2; 
private static final double THIRD = h/3; 
private static final double SIXTH = h/6; 


DoublePendulumThread(SurfaceHolder holder, int width, int height, Context context){ 
    this.holder = holder; 
    this.context = context; 
    this.width = width; 
    this.height = height; 

    //Setting sizes that require Context to be set 
    RADIUS = dpToPx(20); 
    l1 = dpToPx(150); 
    l2 = dpToPx(150); 
    state[0] = Math.PI/8; 

    //Setting up paints for rendering on Canvas 
    int bobColor = context.getResources().getColor(R.color.colorBob); 
    int shadowColor = context.getResources().getColor(R.color.shadowColor); 
    backgroundColor = context.getResources().getColor(R.color.backgroundColor); 
    paint = new Paint(); 
    paint.setColor(bobColor); 
    paint.setShadowLayer(5, -1, 2, shadowColor); 
} 

/* 
Evaluates derivatives for Runge-Kutta. 
*/ 
private void loadDys(double[] y){ 
    dydt[0] = y[2]; //Theta1 
    dydt[1] = y[3]; //Theta2 

    dydt[2] = (-1*g*(2*m1 + m2)*sin(y[0]) - m2*g*sin(y[0] - 2*y[1]) - 2*sin(y[0] - y[1])*m2*(y[3]*y[3]*l2 + y[2]*y[2]*l1*cos(y[0] - y[1])))/(l1*(2*m1 + m2 - m2*cos(2*y[0]-2*y[1]))); 
    dydt[3] = (2*sin(y[0] - y[1])*(y[2]*y[2]*l1*(m1+m2) + g*(m1+m2)*cos(y[0]) + y[3]*y[3]*l2*m2*cos(y[0]-y[1])))/(l2*(2*m1 + m2 - m2*cos(2*y[0]-2*y[1]))); 
} 

/* 
Each time update is run one iteration of the Runge-Kutta method takes place, with time step h. 
*/ 
protected void update(){ 
    if(pRunning && !clicked1 && !clicked2) { 
     for (int i = 0; i < DIMENSION; i++) { 
      midpt[i] = state[i]; 
      prev[i] = state[i]; 
     } 

     loadDys(midpt); 
     for (int i = 0; i < DIMENSION; i++) { 
      state[i] += SIXTH * dydt[i]; 
      midpt[i] = prev[i] + HALF * dydt[i]; 
     } 
     loadDys(midpt); 
     for (int i = 0; i < DIMENSION; i++) { 
      state[i] += THIRD * dydt[i]; 
      midpt[i] = prev[i] + HALF * dydt[i]; 
     } 
     loadDys(midpt); 
     for (int i = 0; i < DIMENSION; i++) { 
      state[i] += THIRD * dydt[i]; 
      midpt[i] = prev[i] + h * dydt[i]; 
     } 
     loadDys(midpt); 
     for (int i = 0; i < DIMENSION; i++) { 
      state[i] += SIXTH * dydt[i]; 
     } 
    }else if(pRunning && clicked1) { 
     state[3] += (-1 * g * Math.sin(state[1]))/l2; 
     state[3] = state[3] * 0.9; 
     state[1] += state[3] * (40 * Math.pow(10, -2)); 
    } 
} 

protected void render(){ 
    Canvas canvas = holder.lockCanvas(); 
    canvas.drawColor(backgroundColor); 

    canvas.drawLine(width/2, height/4, (float) ((width/2) + (l1 * Math.sin(state[0]))), (float) (height/4 + l1 * Math.cos(state[0])), paint); 
    canvas.drawLine((float) ((width/2) + (l1 * Math.sin(state[0]))), (float) (height/4 + l1 * Math.cos(state[0])), (float) ((width/2) + (l1 * Math.sin(state[0])) + (l2 * Math.sin(state[1]))), (float) (height/4 + l1 * Math.cos(state[0]) + l2 * Math.cos(state[1])), paint); 
    canvas.drawCircle((float) ((width/2) + (l1 * Math.sin(state[0]))), (float) (height/4 + l1 * Math.cos(state[0])), RADIUS, paint); 
    canvas.drawCircle((float) ((width/2) + (l1 * Math.sin(state[0])) + (l2 * Math.sin(state[1]))), (float) (height/4 + l1 * Math.cos(state[0]) + l2 * Math.cos(state[1])), RADIUS, paint); 

    holder.unlockCanvasAndPost(canvas); 
} 

void updatePos(MotionEvent e){ 
    if(clicked1){ 
     l1 = (int)Math.round(Math.sqrt(((e.getX()-(width/2))*(e.getX()-(width/2)))+((e.getY()-height/4)*(e.getY()-height/4)))); 
     if(e.getY() - height/4 < 0) { 
      if (Math.round(e.getX() - width/2) == 0) { 
       state[0] = Math.PI; 
      } else { 
       state[0] = Integer.signum(Math.round((e.getX() - (width/2)))) * Math.acos((Math.abs(e.getX() - (width/2))/l1)) + Integer.signum(Math.round((e.getX() - (width/2)))) * Math.PI/2; 
      } 
     }else if(Math.round(e.getY() - (height/4)) == 0){ 
      state[0] = Integer.signum(Math.round(e.getX() - (width/2))) * Math.PI/2; 
     }else{ 
      state[0] = Math.asin((e.getX()-(width/2))/l1); 
     } 
    }else if(clicked2){ 
     l2 = (int)Math.round(Math.sqrt(((e.getX()-((width/2) + (l1 * Math.sin(state[0]))))*(e.getX()-((width/2) + (l1 * Math.sin(state[0])))))+((e.getY()-(height/4 + l1 * Math.cos(state[0])))*(e.getY()-(height/4 + l1 * Math.cos(state[0])))))); 
     if(e.getY() - (height/4 + l1 * Math.cos(state[0])) < 0){ 
      if(Math.round(e.getX() - ((width/2) + l1*sin(state[0]))) == 0){ 
       state[1] = Math.PI; 
      }else { 
       state[1] = Integer.signum((int) Math.round((e.getX() - ((width/2) + (l1 * Math.sin(state[0])))))) * Math.acos((Math.abs(e.getX() - ((width/2) + (l1 * Math.sin(state[0]))))/l2)) + Integer.signum((int) Math.round((e.getX() - ((width/2) + (l1 * Math.sin(state[0])))))) * Math.PI/2; 
      } 
     }else if(Math.round(e.getY() - (height/4 + l1 * Math.cos(state[0]))) == 0) { 
      state[1] = Integer.signum((int) Math.round(e.getX() - ((width/2) + l1*sin(state[0])))) * Math.PI/2; 
     }else{ 
      state[1] = Math.asin((e.getX()-((width/2) + (l1 * Math.sin(state[0]))))/l2); 
     } 
    } 
} 

void click(MotionEvent e){ 
    if((e.getX() - ((width/2) + (l1 * Math.sin(state[0])) + (l2 * Math.sin(state[1]))))*(e.getX() - ((width/2) + (l1 * Math.sin(state[0])) + (l2 * Math.sin(state[1])))) + (e.getY() - (height/4 + l1 * Math.cos(state[0]) + l2 * Math.cos(state[1])))*(e.getY() - (height/4 + l1 * Math.cos(state[0]) + l2 * Math.cos(state[1]))) <= RADIUS*RADIUS){ 
     clicked2 = true; 
    }else { 
     clicked1 = true; 
    } 
    updatePos(e); 
} 

void unclick(){ 
    if(clicked1 || clicked2) { 
     state[2] = 0; 
     state[3] = 0; 
     for (int i = 0; i < DIMENSION; i++) { 
      dydt[i] = 0; 
      midpt[i] = 0; 
      prev[i] = 0; 
     } 
     clicked1 = false; 
     clicked2 = false; 
    } 
} 

private int dpToPx(int dp) { 
    DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); 
    return Math.round(dp * (displayMetrics.xdpi/DisplayMetrics.DENSITY_DEFAULT)); 
} 

private static double sin(double x){ 
    return Math.sin(x); 
} 
private static double cos(double x){ 
    return Math.cos(x); 
} 

Voici l'activité principale dans laquelle le fragment est intégré dans le pager de vue.

<?xml version="1.0" encoding="utf-8"?> 
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/. apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
tools:context="com.astarphysics.wikidpendulum.MainActivity" 
> 

<android.support.constraint.ConstraintLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    app:layout_behavior="@string/appbar_scrolling_view_behavior"> 

    <com.astarphysics.wikidpendulum.PendulumViewPager 
     android:id="@+id/view_pager" 
     android:layout_width="0dp" 
     android:layout_height="0dp" 
     tools:layout_constraintTop_creator="1" 
     tools:layout_constraintRight_creator="1" 
     tools:layout_constraintBottom_creator="1" 
     android:layout_marginStart="8dp" 
     app:layout_constraintBottom_toBottomOf="parent" 
     android:layout_marginEnd="8dp" 
     app:layout_constraintRight_toRightOf="parent" 
     android:layout_marginTop="8dp" 
     tools:layout_constraintLeft_creator="1" 
     android:layout_marginBottom="8dp" 
     app:layout_constraintLeft_toLeftOf="parent" 
     app:layout_constraintTop_toTopOf="parent" 
     android:layout_marginLeft="8dp" 
     android:layout_marginRight="8dp"> 

    </com.astarphysics.wikidpendulum.PendulumViewPager> 
</android.support.constraint.ConstraintLayout> 

<android.support.design.widget.AppBarLayout 
android:layout_height="wrap_content" 
android:layout_width="match_parent"> 

    <android.support.v7.widget.Toolbar 
     app:layout_scrollFlags="enterAlways" 
     android:id="@+id/toolbar" 
     android:layout_height="192dp" 
     android:layout_width="match_parent" 
     app:contentInsetLeft="0dp" 
     app:contentInsetStart="0dp"> 
     <LinearLayout 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:orientation="vertical"> 

      <RelativeLayout 
       android:layout_width="match_parent" 
       android:layout_height="144dp"> 
       <LinearLayout 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_alignParentEnd="true" 
        android:layout_alignParentRight="true" 
        android:padding="10dp"> 

       <android.support.v7.widget.AppCompatImageButton 
        android:id="@+id/stop_button" 
        android:layout_width="48dp" 
        android:layout_height="48dp" 
        app:srcCompat="@drawable/ic_pause_white_48dp" 
        android:background="?attr/selectableItemBackgroundBorderless" 
        android:layout_marginRight="10dp" 
        android:layout_marginEnd="10dp"/> 

       <android.support.v7.widget.AppCompatImageButton 
        android:id="@+id/help_button" 
        android:layout_width="48dp" 
        android:layout_height="48dp" 
        app:srcCompat="@drawable/ic_help_white_48dp" 
        android:background="?attr/selectableItemBackgroundBorderless" /> 

       </LinearLayout> 

       <LinearLayout 
        android:layout_width="match_parent" 
        android:layout_height="match_parent" 
        android:gravity="center" 
        android:orientation="vertical"> 

        <ImageView 
         android:layout_width="80dp" 
         android:layout_height="80dp" 
         android:src="@drawable/icon"/> 

        <TextView 
         android:layout_width="150dp" 
         android:layout_height="wrap_content" 
         android:text="@string/app_name" 
         android:gravity="center" 
         android:textSize="24sp" 
         android:fontFamily="sans-serif-smallcaps" 
         android:textColor="@color/textColor"/> 

       </LinearLayout> 
      </RelativeLayout> 

      <android.support.design.widget.TabLayout 
       android:id="@+id/pager_tabs" 
       android:layout_width="match_parent" 
       android:layout_height="48dp"> 

      </android.support.design.widget.TabLayout> 

     </LinearLayout> 
    </android.support.v7.widget.Toolbar> 
</android.support.design.widget.AppBarLayout> 


</android.support.design.widget.CoordinatorLayout> 

Si vous pensez qu'il ya quelque chose d'autre, alors je peux ajouter le code.

Merci.

+0

L'image unique pendule semble avoir une sorte de canevas sur la zone sombre. Dans l'image à double pendule, ce canevas ne couvre que la moitié de la zone sombre. Quelle est cette zone couverte par le canevas? L'écrasement peut être lié à l'écrasement de cette zone de canevas. Utilisez l'inspecteur de disposition dans Android Studio pour voir ces deux images. Vous pouvez également envoyer du code/XML qui traite de cette zone. – Cheticamp

+0

Merci pour la réponse. La page entière est une vue de surface, le pendule est libre de prendre la moitié inférieure de l'écran dans l'exemple unique, il est juste dans les images qu'il n'a pas. Je ne suis pas sûr de ce que vous voulez dire par le fait qu'il y ait un canevas. –

+0

À propos du canevas: Regardez l'image à deux pendules. La moitié supérieure de la zone sombre avec le pendule a un aspect plus léger et dépoli. La moitié inférieure est beaucoup plus sombre. Avec le pendule unique, tout est noir et de la même couleur. C'est ce que je remets en question. Postez votre classe 'SurfacePanel' et le code XML associé. – Cheticamp

Répondre

1

Le simple fait de changer de page dans ViewPager ne force pas les fragments à traverser leur cycle de vie ou à provoquer une recréation du SurfaceView. Si vous appuyez sur recents ou home, puis que vous revenez à l'application, les SurfaceView sont recréés et cela semble corriger le problème que vous voyez.

Dans le cas où le problème est un problème subtil lié à votre mise en page, je vous suggère de le simplifier autant que possible. J'ai retravaillé les deux dispositions principales pour les simplifier comme vous pouvez le voir ci-dessous. Si vous décidez d'emprunter cette route, vous devrez peut-être modifier quelques éléments dans la mise en page principale pour obtenir le dimensionnement/positionnement comme vous le souhaitez. Vous ne devriez pas avoir à faire de changements structurels.

Une autre chose à essayer si ce qui précède ne fonctionne pas est de forcer la recréation d'un fragment à chaque fois qu'il est sélectionné pour l'API 26+. Cela forcera une ré-instanciation du fragment et de la mise en page et devrait corriger le problème.

Si les nouvelles dispositions fonctionnent, ce serait mieux; Si vous devez faire une re-création lors de la sélection de l'onglet, c'est juste une solution de rechange. Si vous trouvez quel est le problème sous-jacent, veuillez le poster ici. Je serais intéressé de savoir ce que c'est. Peut-être qu'un autre lecteur de cette question peut aller au fond des choses.

pendulum_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" 
    tools:context=".MainActivity"> 

    <android.support.v7.widget.Toolbar 
     android:id="@+id/toolbar" 
     android:layout_width="match_parent" 
     android:layout_height="144dp" 
     app:contentInsetLeft="0dp" 
     app:contentInsetStart="0dp"> 

     <RelativeLayout 
      android:layout_width="match_parent" 
      android:layout_height="match_parent"> 

      <LinearLayout 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_alignParentEnd="true" 
       android:layout_alignParentRight="true" 
       android:padding="10dp"> 

       <android.support.v7.widget.AppCompatImageButton 
        android:id="@+id/stop_button" 
        android:layout_width="48dp" 
        android:layout_height="48dp" 
        android:layout_marginEnd="10dp" 
        android:layout_marginRight="10dp" 
        android:background="?attr/selectableItemBackgroundBorderless" 
        app:srcCompat="@drawable/ic_pause_white_48dp" /> 

       <android.support.v7.widget.AppCompatImageButton 
        android:id="@+id/help_button" 
        android:layout_width="48dp" 
        android:layout_height="48dp" 
        android:background="?attr/selectableItemBackgroundBorderless" 
        app:srcCompat="@drawable/ic_help_white_48dp" /> 

      </LinearLayout> 

      <LinearLayout 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:gravity="center" 
       android:orientation="vertical"> 

       <ImageView 
        android:layout_width="80dp" 
        android:layout_height="80dp" 
        android:src="@drawable/icon" /> 

       <TextView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:fontFamily="sans-serif-smallcaps" 
        android:gravity="center" 
        android:text="@string/app_name" 
        android:textColor="#FF000000" 
        android:textSize="24sp" /> 

      </LinearLayout> 
     </RelativeLayout> 
    </android.support.v7.widget.Toolbar> 

    <com.example.viewpagerbase.PendulumViewPager 
     android:id="@+id/view_pager" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

     <android.support.design.widget.TabLayout 
      android:id="@+id/pager_tabs" 
      android:layout_width="match_parent" 
      android:layout_height="48dp" /> 
    </com.example.viewpagerbase.PendulumViewPager> 
</LinearLayout> 

fragment_main.xml

<com.example.viewpagerbase.MySurfaceView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/surfaceView" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 

Voici une façon de forcer un nouveau fragment lorsqu'il est sélectionné. Il existe d'autres méthodes disponibles en ligne si vous les recherchez.

Ajoutez ce qui suit à votre ViewPager et appelez de chaque constructeur. Cela va configurer un écouteur de page pour API 26+. Cet écouteur se déclenche chaque fois qu'une page différente est sélectionnée.

private void init() { 
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { 
     return; 
    } 
    addOnPageChangeListener(new OnPageChangeListener() { 
     @Override 
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
     } 

     @Override 
     public void onPageSelected(int position) { 
      MainActivity.SectionsPagerAdapter adapter = 
       // Your adapter name goes here 
       ((MainActivity.SectionsPagerAdapter) getAdapter()); 
      adapter.invalidateFragment(position); 
     } 

     @Override 
     public void onPageScrollStateChanged(int position) { 
     } 
    }); 
} 

Ajouter ce qui suit à votre adaptateur:

private List<SurfacePanelFragment> fragments = new ArrayList<>(PAGE_COUNT); 

    @Override 
    public SurfacePanelFragment getItem(int position) { 
     if (fragments.get(position) == null) { 
      fragments.set(position, SurfacePanelFragment.newInstance()); 
     } 
     return fragments.get(position); 
    } 

    @Override 
    public int getItemPosition(Object object) { 
     return (fragments.contains(object)) ? POSITION_UNCHANGED : POSITION_NONE; 
    } 

    public void invalidateFragment(int position) { 
     fragments.set(position, null); 
     notifyDataSetChanged(); 
    } 

    private static final int PAGE_COUNT = 2; 
+0

Aucune différence, la vue de surface apparaît toujours écrasée une fois que vous passez à la double page ou retour à l'unique –

+0

Selon la vue de disposition du moniteur de l'appareil Android, le pager de vue, les fragments et les vues de surface remplissent l'espace qu'ils devraient peut voir qu'il a été écrasé sur l'émulateur ou l'appareil. @Cheticamp –

+0

@ BenjaminRogers-Newsome Tout cela est juste dommage. :-(Essayez quelque chose que je viens de remarquer, mettez votre application dans son état écroulé, puis allez dans l'écran [recents] (https://developer.android.com/guide/components/activities/recents.html) mais don ' – Cheticamp