How to implement 3d effect zooming in viewpager android - java

I need help regarding the viewpager. Basically I have a viewpager contained in a page container:
package com.example.CustomViews;
/**
* Created by imrankhan on 4/29/2015.
*/
import android.content.Context;
import android.graphics.Camera;
import android.graphics.Matrix;
import android.graphics.Point;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Transformation;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.example.imrankhan.newlawdojo.DashboardActivity;
import com.example.imrankhan.newlawdojo.QuizActivity;
import com.example.imrankhan.newlawdojo.R;
/**
* PagerContainer: A layout that displays a ViewPager with its children that are outside
* the typical pager bounds.
*/
public class PageContainer extends FrameLayout implements ViewPager.OnPageChangeListener {
private ViewPager mPager;
boolean mNeedsRedraw = false;
private Camera mCamera = new Camera();
private int mMaxRotationAngle = 60;
private int mMaxZoom = -120;
public PageContainer(Context context) {
super(context);
init();
}
public PageContainer(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public PageContainer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
//Disable clipping of children so non-selected pages are visible
setClipChildren(false);
//Child clipping doesn't work with hardware acceleration in Android 3.x/4.x
//You need to set this value here if using hardware acceleration in an
// application targeted at these releases.
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
#Override
protected void onFinishInflate() {
try {
mPager = (ViewPager) getChildAt(0);
mPager.setOnPageChangeListener(this);
} catch (Exception e) {
throw new IllegalStateException("The root child of PagerContainer must be a ViewPager");
}
}
public ViewPager getViewPager() {
return mPager;
}
private Point mCenter = new Point();
private Point mInitialTouch = new Point();
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mCenter.x = w / 4;
mCenter.y = h / 4;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
//We capture any touches not already handled by the ViewPager
// to implement scrolling from a touch outside the pager bounds.
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mInitialTouch.x = (int)ev.getX();
mInitialTouch.y = (int)ev.getY();
default:
ev.offsetLocation(mCenter.x - mInitialTouch.x, mCenter.y - mInitialTouch.y);
break;
}
return mPager.dispatchTouchEvent(ev);
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//Force the container to redraw on scrolling.
//Without this the outer pages render initially and then stay static
if (mNeedsRedraw) invalidate();
}
#Override
public void onPageSelected(int position) {
View v =this.getViewPager().getChildAt(position);
}
private void transformImageBitmap(View child, Transformation t, int rotationAngle) {
mCamera.save();
final Matrix imageMatrix = t.getMatrix();;
final int imageHeight = child.getLayoutParams().height;;
final int imageWidth = child.getLayoutParams().width;
final int rotation = Math.abs(rotationAngle);
mCamera.translate(0.0f, 0.0f, 100.0f);
if ( rotation < mMaxRotationAngle ) {
float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));
mCamera.translate(0.0f, 0.0f, zoomAmount);
}
mCamera.rotateY(rotationAngle);
mCamera.getMatrix(imageMatrix);
imageMatrix.preTranslate(-(imageWidth/2), -(imageHeight/2));
imageMatrix.postTranslate((imageWidth/2), (imageHeight/2));
mCamera.restore();
}
#Override
public void onPageScrollStateChanged(int state) {
mNeedsRedraw = (state != ViewPager.SCROLL_STATE_IDLE);
}
}
on onPageSelected event I got the view I need to zoom in when selected and zoom out after selecting another item. Please help me out. I added an image to give you an idea what I want.
http://i.stack.imgur.com/xtE89.png

Related

A fragment that hosts a SurfaceView only draws onto Canvas once

Good Evening,
I minimized my large project onto a small scale one which still keeps all the aspects of issue I'm having. I'm using an activity that draws SurfaceView background underneath a single Button. On press that Button adds a new fragment (to an empty FrameLayout that's in MainActivities XML layout) which as well holds SurfaceView and three buttons in ConstraintLayout. Button works as intended and calls the Fragments, but only the static layout part is being drawn(three buttons) as for SurfaceView it only draws Initial Canvas and keeps redrawing same Frame, even tho Thread keeps on calling the Draw method with updated values(in this case Color). ThreadPool is used to create two instances that call update and draw methods for SurfaceView(MaintActivity and Fragment) class objects(this part works as intended).
I'm also getting this line in Log, right about where the issue begins.
D/MY FRAGMENT VIEW: >> INIT
D/MY FRAGMENT VIEW: SURFACE CREATED
D/MY_FRAGMENT: SURFACE CREATED
D/MY FRAGMENT VIEW: SURFACE CHANGED
D/MY_FRAGMENT: SURFACE CHANGED
D/MY FRAGMENT VIEW: DRAW PLANET
D/: HostConnection::get() New Host Connection established 0xb2d1d780, tid 9982
D/MY FRAGMENT VIEW: DRAW PLANET
D/MY FRAGMENT VIEW: DRAW PLANET
D/MY FRAGMENT VIEW: DRAW PLANET
D/MY FRAGMENT VIEW: DRAW PLANET
Code samples bellow:
package com.badcompany.testfragmentview;
import android.os.Bundle;
import android.support.constraint.ConstraintLayout;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
private MyActivityView gameView;
private static final String TAG = "MAIN";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
gameView = findViewById(R.id.myview);
SurfaceHolder gholder = gameView.getHolder();
gholder.addCallback(this);
gameView.setLayoutParams(new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.WRAP_CONTENT, ConstraintLayout.LayoutParams.WRAP_CONTENT));
Button btn_map = findViewById(R.id.start);
btn_map.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
displayMapFragment();
return true;
}
return false;
}
});
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
Log.d(TAG, ">> SURFACE CREATED");
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
Log.d(TAG, ">> SURFACE CHANGED");
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
Log.d(TAG, ">> SURFACE DESTROYED");
}
private void displayMapFragment() {
MyFragment myFragment = new MyFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.myMapSpace, myFragment).addToBackStack(null)
.commit();
/*fragmentTransaction.add(R.id.fragment_container, simpleFragment).addToBackStack(null).commit();
mButton.setText(R.string.close);
isFragmentDisplayed = true;*/
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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=".MainActivity">
<com.badcompany.testfragmentview.MyActivityView
android:id="#+id/myview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:id="#+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<FrameLayout
android:id="#+id/myMapSpace"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
MyActivityView.java
package com.badcompany.testfragmentview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
public class MyActivityView extends ParentGameView implements SurfaceHolder.Callback {
private static final String TAG = "MY ACTIVITY VIEW";
public MyActivityView(Context context) {
super(context);
}
public MyActivityView(Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(this);
setFocusable(true);
}
public MyActivityView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public MyActivityView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
Log.d(TAG, "SURFACE CREATED");
MyExecutor.getInstance().execute(new GameRunnable(surfaceHolder, this));
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
Log.d(TAG, "SURFACE CHANGED");
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
Log.d(TAG, "SURFACE DESTROYED");
}
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
canvas.drawColor(Color.YELLOW);
Paint paint = new Paint();
paint.setColor(Color.RED);
canvas.drawCircle(x, 100, 200, paint);
}
}
MyFragment.java
package com.badcompany.testfragmentview;
import android.os.Bundle;
import android.support.constraint.ConstraintLayout;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;
public class MyFragment extends Fragment implements SurfaceHolder.Callback {
private static final String TAG = "MY_FRAGMENT";
private MyFragmentView myFragmentView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstanceState) {
//AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
final View rootView = inflater.inflate(R.layout.fragment_my, viewGroup, false);
myFragmentView = rootView.findViewById(R.id.myMapView);
SurfaceHolder mSurfaceHolder = myFragmentView.getHolder();
mSurfaceHolder.addCallback(this);
myFragmentView.setLayoutParams(new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.WRAP_CONTENT, ConstraintLayout.LayoutParams.WRAP_CONTENT));
Button selectGalaxyMap = rootView.findViewById(R.id.btn_select_galaxy_map);
Button selectSolarSystemMap = rootView.findViewById(R.id.btn_select_solar_map);
Button selectPlanetMap = rootView.findViewById(R.id.btn_select_planet_map);
selectGalaxyMap.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d(TAG, "SELECTED GALAXY");
myFragmentView.setColor(1);
Toast.makeText(getActivity(), "SELECT GALAXY", Toast.LENGTH_SHORT).show();
}
});
selectSolarSystemMap.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
myFragmentView.setColor(2);
Log.d(TAG, "SELECTED SYSTEM");
Toast.makeText(getActivity(), "SELECT SYSTEM", Toast.LENGTH_SHORT).show();
}
});
selectPlanetMap.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getActivity(), "SELECT PLANET", Toast.LENGTH_SHORT).show();
myFragmentView.setColor(3);
Log.d(TAG, "SELECTED PLANET");
}
});
return rootView;
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
Log.d(TAG, "SURFACE CREATED");
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
Log.d(TAG, "SURFACE CHANGED");
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
Log.d(TAG, "SURFACE DESTROYED");
}
}
fragment_my.xml
<com.badcompany.testfragmentview.MyFragmentView
android:id="#+id/myMapView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:background="#color/colorPrimary"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<Button
android:id="#+id/btn_select_planet_map"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:background="#null"
android:text="SELECT PLANET"
android:textStyle="bold" />
<Button
android:id="#+id/btn_select_solar_map"
app:layout_constraintRight_toLeftOf="#id/btn_select_planet_map"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:background="#null"
android:text="SELET SYSTEM"
android:textStyle="bold" />
<Button
android:id="#+id/btn_select_galaxy_map"
app:layout_constraintRight_toLeftOf="#id/btn_select_solar_map"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:background="#null"
android:text="SELECT GALAXY"
android:textStyle="bold" />
</android.support.constraint.ConstraintLayout>
package com.badcompany.testfragmentview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
public class MyFragmentView extends ParentGameView implements SurfaceHolder.Callback {
private static final String TAG = "MY FRAGMENT VIEW";
private int Colors;
public MyFragmentView(Context context) {
super(context);
init(context);
}
public MyFragmentView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public MyFragmentView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
public MyFragmentView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
private void init(Context context) {
getHolder().addCallback(this);
Log.d(TAG, ">> INIT ");
setFocusable(true);
}
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
if(Colors == 2)
drawSolarMap(canvas);
else if(Colors == 1)
drawGalaxyMap(canvas);
else drawPlanetMap(canvas);
}
private void drawGalaxyMap(Canvas canvas){
Log.d(TAG, "DRAW GALAXY");
canvas.drawColor(Color.BLACK);
Paint paint = new Paint();
paint.setColor(Color.BLUE);
canvas.drawCircle(x, 100, 100, paint);
}
private void drawSolarMap(Canvas canvas){
Log.d(TAG, "DRAW SYSTEM");
canvas.drawColor(Color.RED);
Paint paint = new Paint();
paint.setColor(Color.BLUE);
canvas.drawCircle(x, 100, 100, paint);
}
private void drawPlanetMap(Canvas canvas){
Log.d(TAG, "DRAW PLANET");
canvas.drawColor(Color.GREEN);
Paint paint = new Paint();
paint.setColor(Color.BLUE);
canvas.drawCircle(x, 100, 100, paint);
}
#Override
public void update() {
super.update();
}
public void setColor(int color){
Colors = color;
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
Log.d(TAG, "SURFACE CREATED");
MyExecutor.getInstance().execute(new GameRunnable(surfaceHolder, this));
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
Log.d(TAG, "SURFACE CHANGED");
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
Log.d(TAG, "SURFACE DESTROYED");
}
}
Extra classes that might not have relevance
GameInterface.java
package com.badcompany.testfragmentview;
/**
* Created by Donatas on 18/12/2018.
*/
import android.graphics.Canvas;
public interface GameInterface {
public void draw(Canvas canvas);
public void update();
}
ParentGameView.java
package com.badcompany.testfragmentview;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.SurfaceView;
public class ParentGameView extends SurfaceView implements GameInterface{
private static final String TAG = "PARENT_GAME_VIEW";
protected int x = 0;
public ParentGameView(Context context) {
super(context);
}
public ParentGameView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ParentGameView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public ParentGameView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
public void update() {
x++;
}
#Override
public void draw(Canvas canvas){
super.draw(canvas);
}
}
MyExecutor.java
package com.badcompany.testfragmentview;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MyExecutor {
private static final ExecutorService executor = Executors.newCachedThreadPool();
public static ExecutorService getInstance(){
return executor;
}
public static void ShutDown(){
executor.shutdown();
}
}
GameRunnable.java
package com.badcompany.testfragmentview;
import android.graphics.Canvas;
import android.util.Log;
import android.view.SurfaceHolder;
public class GameRunnable implements Runnable {
private static final String TAG = "GAME_RUNNABLE";
private volatile boolean running = true;
private final int maxFPS = 30;
private double averageFPS;
private Canvas canvas;
private final SurfaceHolder surfaceHolder;
private volatile ParentGameView gameView;
public GameRunnable(SurfaceHolder surfaceHolder, ParentGameView gameView) {
this.surfaceHolder = surfaceHolder;
this.gameView = gameView;
}
#Override
public void run() {
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
long startTime;
long timeMillis = 1000/maxFPS;
long waitTime;
int frameCount = 0;
long totalTime = 0;
long targetTime = 1000/maxFPS;
while(running){
startTime = System.nanoTime();
canvas = null;
try {
canvas = surfaceHolder.lockCanvas();
if(canvas != null){
synchronized (surfaceHolder){
gameView.update();
gameView.draw(canvas);
}
} else {
Log.d(TAG, "Thread finished work");
return;
}
}
catch (Exception e){
e.printStackTrace();
}
finally {
if(canvas != null){
try{
surfaceHolder.unlockCanvasAndPost(canvas);
}catch (Exception e){e.printStackTrace();}
}
}
timeMillis = (System.nanoTime() - startTime)/1000000;
waitTime = targetTime - timeMillis;
try{
if(waitTime>0)
Thread.sleep(waitTime);
} catch (Exception e){e.printStackTrace();}
totalTime += System.nanoTime() - startTime;
frameCount++;
if(frameCount == maxFPS){
averageFPS = 1000/((totalTime/frameCount)/1000000);
frameCount = 0;
totalTime = 0;
//debug System.out.println("AVERAGE FPS: " + avaragFPS);
}
}
}
}
Thanks for looking into this and if you need additional info leave a comment.
Found an awful solution myself, the issue is that MainActivity does not ask for next frame because it deems fragment view to be finished, calling invalidate() method in a Thread makes the activity to keep on asking for updated views.
If you manage to find a better solution please update this post, thanks.

PinView Subsampling Scale ImageView ERROR

Hey guys I'm trying to use this library (https://github.com/davemorrissey/subsampling-scale-image-view) and I tried out the example mentioned about PinView but I don't get the map displayed nor any Marker. ( the error says cannot cast Subsampling ImageView as PinView how do you solve this ?
MainActivity.java
package com.ascot.mxiv.mapzone;
import android.graphics.PointF;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;
import com.davemorrissey.labs.subscaleview.ImageSource;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PinView imageView = findViewById(R.id.imageView);
imageView.setImage(ImageSource.resource(R.drawable.completemap1).tilingDisabled());
imageView.setPin(new PointF(460f, 320f));
}
}
PinView.java ( no changes made other than the import test.T.drawable as i dont understand it ) and help would be appreciated :D .
import android.content.Context;
import android.graphics.*;
import android.util.AttributeSet;
import android.widget.Toast;
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;
//import com.davemorrissey.labs.subscaleview.test.R.drawable;
public class PinView extends SubsamplingScaleImageView {
private final Paint paint = new Paint();
private final PointF vPin = new PointF();
private PointF sPin;
private Bitmap pin;
Context context;
public PinView(Context context) {
this(context, null);
this.context = context;
}
public PinView(Context context, AttributeSet attr) {
super(context, attr);
this.context = context;
initialise();
}
public void setPin(PointF sPin) {
this.sPin = sPin;
initialise();
invalidate();
}
private void initialise() {
float density = getResources().getDisplayMetrics().densityDpi;
pin = BitmapFactory.decodeResource(this.getResources(), R.drawable.marker);
float w = (density/420f) * pin.getWidth();
float h = (density/420f) * pin.getHeight();
pin = Bitmap.createScaledBitmap(pin, (int)w, (int)h, true);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Don't draw pin before image is ready so it doesn't move around during setup.
if (!isReady()) {
return;
}
paint.setAntiAlias(true);
if (sPin != null && pin != null) {
sourceToViewCoord(sPin, vPin);
float vX = vPin.x - (pin.getWidth()/2);
float vY = vPin.y - pin.getHeight();
canvas.drawBitmap(pin, vX, vY, paint);
Toast.makeText(context,"works ? ", Toast.LENGTH_SHORT).show();
}
}
}
The problem is your in your layout, you should use PinView instead of SubsamplingScaleImageView as shown in the snippet below.
..
<com.example.myapp.PinView
android:id="#+id/floorplan_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

How to change the size of one image in a LayerDrawable

Hello I am working on a android launcher that has a circle background behind all the app icons. I am using a LayerDrawable to get this to work however the circle image is smaller then the app icons see here:
So my question is how do I make the circle icon bigger than the app icon?
heres my circle icon code:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<stroke android:color="#ccc" android:width="5dp" />
<solid android:color="#ffffff"/>
<size android:width="58dp" android:height="58dp"/>
</shape>
</item>
</selector>
and heres my class that generates the app icons:
package Appname.widget;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.support.annotation.ColorInt;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.View;
import android.widget.ImageView;
import appame.R;
import appname.AppManager;
import appname.util.DragAction;
import appname.util.GoodDragShadowBuilder;
import appname.util.LauncherSettings;
import appname.util.Tool;
public class AppItemView extends View implements Drawable.Callback{
public Drawable getIcon() {
return icon;
}
public void setIcon(Drawable icon) {
this.icon = icon;
this.icon.setCallback(this);
}
#Override
public void refreshDrawableState() {
invalidateDrawable(icon);
super.refreshDrawableState();
}
#Override
public void invalidateDrawable(Drawable drawable) {
invalidate();
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public float getIconSize() {
return iconSize;
}
public void setIconSize(float iconSize) {
this.iconSize = iconSize;
}
private float iconSize;
private Drawable icon;
private String label;
public boolean isShortcut;
public Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Rect mTextBound = new Rect();
private boolean noLabel,vibrateWhenLongPress;
private float labelHeight;
public AppItemView(Context context) {
super(context);
init();
}
public AppItemView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init(){
setWillNotDraw(false);
labelHeight = Tool.convertDpToPixel(14,getContext());
textPaint.setTextSize(sp2px(getContext(),14));
textPaint.setColor(Color.DKGRAY);
}
public static int sp2px(Context context, float spValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
#Override
protected void onDraw(Canvas canvas) {
Drawable iconback = getResources().getDrawable(R.drawable.iconback);
LayerDrawable appicon = new LayerDrawable(new Drawable[]{iconback, icon});
appicon.setLayerGravity(0, Gravity.CENTER);
appicon.setLayerGravity(1, Gravity.CENTER);
if (label != null && !noLabel){
textPaint.getTextBounds(label,0,label.length(),mTextBound);
}
//The height should be the same as they have the same text size.
float mHeight = iconSize + (noLabel? 0 : labelHeight);
float heightPadding = (getHeight() - mHeight)/2f;
if (label != null && !noLabel) {
float x = (getWidth()-mTextBound.width())/2f;
if (x < 0)
x = 0;
canvas.drawText(label,x, getHeight() - heightPadding, textPaint);
}
if (appicon != null ) {
canvas.save();
canvas.translate((getWidth()-iconSize)/2,heightPadding);
appicon.setLayerWidth(1, (int) iconSize);
appicon.setLayerHeight(1, (int) iconSize);
appicon.setBounds(0,0,(int)iconSize,(int)iconSize);
appicon.draw(canvas);
canvas.restore();
}
}
public static class Builder{
AppItemView view;
public Builder(Context context){
view = new AppItemView(context);
float iconSize = Tool.convertDpToPixel(LauncherSettings.getInstance(view.getContext()).generalSettings.iconSize, view.getContext());
view.setIconSize(iconSize);
}
public AppItemView getView(){
return view;
}
public Builder setAppItem(AppManager.App app){
view.setIcon(app.icon);
view.setLabel(app.appName);
return this;
}
public Builder withOnClickLaunchApp(final AppManager.App app){
view.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Tool.createScaleInScaleOutAnim(view, new Runnable() {
#Override
public void run() {
Tool.startApp(view.getContext(), app);
}
});
}
});
return this;
}
public Builder withOnLongClickDrag(final AppManager.App app,final DragAction.Action action,#Nullable final OnLongClickListener eventAction){
withOnLongClickDrag(Desktop.Item.newAppItem(app),action,eventAction);
view.setScaleX(0.75f); // <- resized by scaling
view.setScaleY(0.75f);
return this;
}
public Builder withOnLongClickDrag(final Desktop.Item item, final DragAction.Action action, #Nullable final OnLongClickListener eventAction){
view.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
if (view.vibrateWhenLongPress)
v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
Intent i = new Intent();
i.putExtra("mDragData", item);
ClipData data = ClipData.newIntent("mDragIntent", i);
v.startDrag(data, new GoodDragShadowBuilder(v), new DragAction(action), 0);
if (eventAction != null)
eventAction.onLongClick(v);
return true;
}
});
return this;
}
public Builder withOnTouchGetPosition(){
view.setOnTouchListener(Tool.getItemOnTouchListener());
return this;
}
public Builder setTextColor(#ColorInt int color){
view.textPaint.setColor(color);
return this;
}
public Builder setNoLabel(){
view.noLabel = true;
return this;
}
public Builder vibrateWhenLongPress(){
view.vibrateWhenLongPress = true;
return this;
}
public Builder setShortcutItem(final Intent intent){
view.isShortcut = true;
view.setScaleX(0.75f); // <- resized by scaling
view.setScaleY(0.75f);
view.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Tool.createScaleInScaleOutAnim(view, new Runnable() {
#Override
public void run() {
view.getContext().startActivity(intent);
}
});
}
});
view.setScaleX(0.75f); // <- resized by scaling
view.setScaleY(0.75f);
view.setIcon(Tool.getIconFromID(view.getContext(),intent.getStringExtra("shortCutIconID")));
view.setLabel(intent.getStringExtra("shortCutName"));
return this;
}
}
}
Please note the icons are being generated in JAVA NOT XML!
any help would be amazing!
Thanks in advance :)
Before creating the LayerDrawable you could wrap the icon inside a InsetDrawable like so:
Drawable iconWithPadding = new InsetDrawable(icon, paddingSize);
LayerDrawable appicon = new LayerDrawable(new Drawable[]{iconback, iconWithPadding});
That will effectively apply a padding to the icon.

Update Canvas and holder

I am starting with canvas and i need help.
I want to represent real times coordinates in a "room". First when i create surfaceholder i draw the "room" and works fine. My idea is represents differents point in this room.
This is my activity:
package com.example.grafica;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.res.Configuration;
import android.graphics.Point;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TableLayout;
import android.widget.TextView;
#TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
public class MainActivity extends Activity {
private LayoutInflater myInflater = null;
private TextView tx1, tx2, tx3, tx4, tx5, tx6, tx7;
float ancho = (float) 5.20;
float largo = (float) 3.50;
private TableLayout table, table2;
private LinearLayout.LayoutParams params, params2;
private MySurface surface;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.i("telo", "oncreate");
super.onCreate(savedInstanceState);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
setContentView(R.layout.activity_main);
myInflater = LayoutInflater.from(this);
View overView = myInflater.inflate(R.layout.segundacapa, null);
this.addContentView(overView, new LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
}
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
setContentView(R.layout.activity_main);
myInflater = LayoutInflater.from(this);
View overView = myInflater.inflate(R.layout.segundacapaland, null);
this.addContentView(overView, new LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
}
surface =(MySurface)findViewById(R.id.surface);
tx1 = (TextView) findViewById(R.id.textView2);
tx2 = (TextView) findViewById(R.id.textView3);
tx3 = (TextView) findViewById(R.id.textView4);
tx4 = (TextView) findViewById(R.id.textView5);
tx5 = (TextView) findViewById(R.id.textView7);
tx6 = (TextView) findViewById(R.id.textView8);
tx7 = (TextView) findViewById(R.id.textView9);
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
table = (TableLayout) findViewById(R.id.table);
params = (LinearLayout.LayoutParams) table.getLayoutParams();
float ratio = ancho / largo;
float aux = width / ratio;
params.topMargin = (int) aux + 20;
surface.xini = 20;
surface.yini = 20;
surface.xend = width - 20;
surface.yend = aux;
}
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
table2 = (TableLayout) findViewById(R.id.table2);
params2 = (LinearLayout.LayoutParams) table2.getLayoutParams();
float ratio = largo / ancho;
float aux = width / ratio;
params2.leftMargin = (int) (width * ratio) + 20;
surface.xini = 20;
surface.yini = 20;
surface.xend = width * ratio;
surface.yend = height - 220;
}
surface.ini();
surface.update();
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent evento) {
return super.onKeyDown(keyCode, evento);
}
}
And this my surface class:
package com.example.grafica;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MySurface extends SurfaceView implements SurfaceHolder.Callback {
private Paint pincel = new Paint();
private Canvas canvas;
public float xini = 0;
public float yini = 0;
public float xend = 0;
public float yend = 0;
public float coordinatex =(float) 2.50;
public float coordinatety=(float) 1.75;
private SurfaceHolder holder;
public MySurface(Context context, AttributeSet attr) {
super(context,attr);
}
public void ini(){
getHolder().addCallback(this);
}
public void update(){
holder.lockCanvas();
pincel.setColor(Color.BLUE);
pincel.setStrokeWidth(25);
canvas.drawPoint(100, 100, pincel);
holder.unlockCanvasAndPost(canvas);
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder arg0) {
holder = arg0;
canvas = arg0.lockCanvas();
canvas.drawColor(Color.WHITE);
pincel.setColor(Color.BLACK);
pincel.setStrokeWidth(8);
pincel.setStyle(Style.STROKE);
RectF rect = new RectF();
rect.set(xini, yini, xend, yend);
canvas.drawRect(rect, pincel);
pincel.setColor(Color.RED);
pincel.setStrokeWidth(25);
canvas.drawPoint(xini, yend, pincel);
pincel.setColor(Color.BLUE);
pincel.setStrokeWidth(25);
canvas.drawPoint(xend, yend, pincel);
pincel.setColor(Color.GREEN);
pincel.setStrokeWidth(25);
canvas.drawPoint(xini, yini, pincel);
pincel.setColor(Color.YELLOW);
pincel.setStrokeWidth(25);
canvas.drawPoint(xend, yini, pincel);
arg0.unlockCanvasAndPost(canvas);
}
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
Log.e("surfaceDestroyed ", "Hilo detenido ");
}
#Override
public void onDraw(Canvas canvas) {
}
}
In conclussion, with surface.ini(); i call to SurfaceCreated and draw the room, and my idea is that with surface.upddate(); represents a point in this room. It is possible reuse same canvas and holder? how?
I read something about invalidate() function, could be help me? how use this function?
thanks
You'll need a thread to manage the view redrawing effect :
From run method either :
Code your drawing method
Call directly onDraw
Here is an example Example on how to subclass and use SurfaceView

trying to change color through a menu

I am writing an Android painter.
this is my main:
package com.example.hwpainterandfilemanager;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Color;
import android.view.Menu;
import android.view.MenuItem;
public class MainPainter extends Activity {
MyPainter painter ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
painter = new MyPainter(getApplicationContext());
setContentView(R.layout.activity_main_painter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main_painter, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()){
case (R.id.Blue ):{
painter.mColor = Color.BLUE;
break;
}
case (R.id.Red ):{
painter.mColor=Color.RED;
break;
}
case (R.id.Yellow ):{
painter.mColor = Color.YELLOW;
break;
}
case (R.id.Green ):{
painter.mColor = Color.GREEN;
break;
}
}
return super.onOptionsItemSelected(item);
}
}
This is MyPanter:
package com.example.hwpainterandfilemanager;
import java.util.Vector;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
public class MyPainter extends View {
Vector<MyDot> allDots;
int mColor;
Paint p ;
public MyPainter(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
init();
}
public MyPainter(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
init();
}
public MyPainter(Context context) {
super(context);
// TODO Auto-generated constructor stub
init();
}
public void init(){
allDots = new Vector <MyDot> ();
mColor = Color.BLUE;
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
p= new Paint();
p.setStrokeWidth(5);
for (int i =0 ; i<allDots.size();i++){
p.setColor(allDots.get(i).mColor);
canvas.drawPoint(allDots.get(i).mX, allDots.get(i).mY, p);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int x,y;
if(MotionEvent.ACTION_DOWN==event.getAction() || MotionEvent.ACTION_MOVE==event.getAction()){
x= (int) event.getX();
y= (int) event.getY();
MyDot tmp;
tmp = new MyDot(x, y, mColor);
Log.i("Painter Color", "" + mColor);
allDots.add(tmp);
invalidate();
}
// TODO Auto-generated method stub
return true;
}
}
and MyDot class:
package com.example.hwpainterandfilemanager;
public class MyDot {
int mX =0;
int mY =0;
int mColor;
public MyDot (int x, int y, int color) {
mX=x;
mY=y;
mColor = color;
}
}
when trying to change the color from blue to any other color the color will not change and stay the same.
the only way I find it working is by setting mColor as static but it is not the way i want to solve this issue.
what am I missing ?
thx,
Avner.
You're creating two instances of Painter class and you're updating wrong instance. Problem is in MyPainter activity. Change this:
painter = new MyPainter(getApplicationContext());
setContentView(R.layout.activity_main_painter);
Into this:
painter = new MyPainter(getApplicationContext());
setContentView(painter);

Categories