I have a pie chart and mapview on the screen. Between chart and mapview, there is a small imageview. When imageview moves, chart and mapview are supposed to have grow and shrink. It works, but when I move imageview, app is shaking. I want their sizes to change smoothly. I think it is due to pie chart. How can I fix this? Thanks. Here is my Java code :
final LinearLayout aboveLinear = (LinearLayout) findViewById(R.id.aboveLinear);
final LinearLayout belowLinear = (LinearLayout) findViewById(R.id.belowLinear);
final ImageView imageView2 = (ImageView) findViewById(R.id.imageView2);
detector = new GestureDetectorCompat(this, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
if ( aboveLinear == null || belowLinear == null ) {
return true;
}
distanceY*=-1;
int height = aboveLinear.getHeight ( ) + mapview.getHeight ( );
ViewGroup.LayoutParams layoutParams = aboveLinear.getLayoutParams ( );
if ( ( int ) distanceY + layoutParams.height < minH )
layoutParams.height = minH;
else if ( ( int ) distanceY + layoutParams.height > height - minH )
layoutParams.height = height - minH;
else
layoutParams.height = ( int ) distanceY + layoutParams.height;
ViewGroup.LayoutParams layoutParams2 = belowLinear.getLayoutParams ( );
layoutParams2.height = height - layoutParams.height;
aboveLinear.setLayoutParams ( layoutParams );
belowLinear.setLayoutParams ( layoutParams2 );
return true;
}
});
imageView2.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(final View view, final MotionEvent motionEvent) {
return detector.onTouchEvent(motionEvent);
}
});
mapview = (MapView) findViewById(R.id.mapview);
mapview.onCreate(savedInstanceState);
chart1 = (PieChart) findViewById(R.id.chart1);
chart1.setUsePercentValues(true);
chart1.setDescription("");
chart1.setExtraOffsets(5, 10, 5, 5);
chart1.setDragDecelerationFrictionCoef(0.95f);
Here is my xml code :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
xmlns:mapbox="http://schemas.android.com/apk/res-auto"
android:id="@+id/root">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/aboveLinear">
<com.github.mikephil.charting.charts.PieChart
android:id="@+id/chart1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:scaleType="fitXY"/>
</LinearLayout>
<ImageView
android:id="@+id/imageView2"
android:layout_width="match_parent"
android:layout_height="25dp"
android:layout_alignParentTop="true"
android:clickable="true"
android:scaleType="fitXY"
android:src="@drawable/red"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/belowLinear">
<com.mapbox.mapboxsdk.maps.MapView
android:layout_height="match_parent"
android:scaleType="fitXY"
android:id="@+id/mapview"
android:layout_width="fill_parent"
mapbox:access_token="@string/accessToken"
mapbox:style_url="@string/style_mapbox_streets"
mapbox:center_latitude="41.885"
mapbox:center_longitude="-87.679"
mapbox:zoom="12"
mapbox:tilt="20"/>
</LinearLayout>
</LinearLayout>
You dont need animation to do this.
Dont calculate height
every time.
This solution will help you
private MapView mapview;
PieChart chart1;
GestureDetectorCompat detector;
int minH = 100;
int height = 0;
private LinearLayout aboveLinear;
private LinearLayout belowLinear;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mappie);
aboveLinear = (LinearLayout) findViewById(R.id.aboveLinear);
belowLinear = (LinearLayout) findViewById(R.id.belowLinear);
final ImageView imageView2 = (ImageView) findViewById(R.id.imageView2);
detector = new GestureDetectorCompat(this, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
if ( aboveLinear == null || belowLinear == null ) {
return true;
}
if(distanceY > 90){
distanceY = 90;
}
else if(distanceY < -90){
distanceY = -90;
}
distanceY*=-1;
if(height == 0){
height = aboveLinear.getMeasuredHeight()+belowLinear.getMeasuredHeight();// calculate only once
}
Log.wtf("Mapie","Height :"+height);
int toHeightAL, toHeightBl;
ViewGroup.LayoutParams layoutParams = aboveLinear.getLayoutParams ( );
if(layoutParams.height == 0){
layoutParams.height = height/2; // params.height returns 0 before setting the value for it
}
if ( ( int ) distanceY + layoutParams.height < minH )
toHeightAL = minH;
else if ( ( int ) distanceY + layoutParams.height > height - minH )
toHeightAL = height - minH ;
else
toHeightAL = ( int ) distanceY + layoutParams.height;
ViewGroup.LayoutParams layoutParams2 = belowLinear.getLayoutParams ();
toHeightBl = height - layoutParams.height;
layoutParams.height = toHeightAL;
layoutParams2.height = toHeightBl;
aboveLinear.setLayoutParams ( layoutParams );
belowLinear.setLayoutParams ( layoutParams2 );
return true;
}
});
imageView2.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(final View view, final MotionEvent motionEvent) {
return detector.onTouchEvent(motionEvent);
}
});
mapview = (MapView) findViewById(R.id.mapview);
mapview.onCreate(savedInstanceState);
chart1 = (PieChart) findViewById(R.id.chart1);
chart1.setUsePercentValues(true);
chart1.setDescription("");
chart1.setExtraOffsets(5, 10, 5, 5);
chart1.setDragDecelerationFrictionCoef(0.95f);
}
You can try to use an animation for resizing this view. Instead to set height and width equals to a value, maybe you have to animate from starting height/width to the height/width you want to use.
Check here https://stackoverflow.com/a/8162779/6093353. This user wrote a very simple custom animation to resize a view, but you can write the animation you want your own.
Let me know if this helps you!
Try to replace the OnScroll function with this (i didn't tried this, nor typed it in a java IDE so maybe i'm not accessing the properties the right way as i'm more used to C#) :
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
{
if (aboveLinear == null || belowLinear == null)
{
return true;
}
int currentY = e1.getY();
float ratio = abovelinear.getHeight() / (aboveLinear.Bottom - currentY);
aboveLinear.SetScaleY( aboveLinear.GetScaleY()- ratio);
belowLinear.SetScaleY(belowLinear.GetScaleY() +ratio);
return true;
}
});
This should work only one way (down to top), but with some time you should be able to obtain what you are looking for.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With