I want to create rect and circle by geting params from client. I can draw only one of them. But i can draw only one of them. In below code i get default circle and my rect.
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
String colors[] = {"Red","Blue","White","Yellow","Black", "Green","Purple","Orange","Grey"};
EditText xc;
EditText yc;
EditText xr;
EditText yr;
EditText hr;
EditText wr;
EditText rc;
Spinner ColorC;
Spinner ColorR;
RelativeLayout display;
DrawShapes circle;
DrawShapes rect;
Button draw;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//circle
ColorC = (Spinner) findViewById(R.id.ColorSpinner0);
xc = (EditText) findViewById(R.id.xc);
yc = (EditText) findViewById(R.id.yc);
rc = (EditText) findViewById(R.id.rc);
//rect
ColorR = (Spinner) findViewById(R.id.ColorSpinner);
xr = (EditText) findViewById(R.id.xr);
yr = (EditText) findViewById(R.id.yr);
hr = (EditText) findViewById(R.id.hr);
wr = (EditText) findViewById(R.id.wr);
draw = (Button) findViewById(R.id.draw);
display = (RelativeLayout) findViewById(R.id.display);
draw.setOnClickListener(this);
ArrayAdapter<String> spinnerArrayAdapter0 = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, colors);
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, colors);
spinnerArrayAdapter0.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
ColorC.setAdapter(spinnerArrayAdapter0);
ColorR.setAdapter(spinnerArrayAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onClick(View v) {
if ( xc.getText().toString().equals("") ||
yc.getText().toString().equals("") ||
rc.getText().toString().equals("") ||
xr.getText().toString().equals("") ||
yr.getText().toString().equals("") ||
wr.getText().toString().equals("") ||
hr.getText().toString().equals("")) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.errMsg);
builder.setTitle("Fields Require!");
builder.setPositiveButton("OK", null);
builder.create();
builder.show();
} else
createShapes();
}
//create shapes
public void createShapes(){
//circle
int x = Integer.parseInt(xc.getText().toString());
int y = Integer.parseInt(yc.getText().toString());
int rrr = Integer.parseInt(rc.getText().toString());
int cc =Color.parseColor(ColorC.getSelectedItem().toString());
circle = new DrawShapes(x,y,rrr,cc,this);
display.addView(circle);
//rect
int xx = Integer.parseInt(xr.getText().toString());
int yy = Integer.parseInt(yr.getText().toString());
int hh = Integer.parseInt(hr.getText().toString());
int ww = Integer.parseInt(wr.getText().toString());
int cr =Color.parseColor(ColorR.getSelectedItem().toString());
rect = new DrawShapes(xx,yy,xx+hh,yy+ww,cr,this);
display.addView(rect);
}
}
ShapesConst.java
package com.example.alexa.shapes;
import android.content.Context;
import android.graphics.Color;
import android.view.View;
public class ShapesConst extends View {
private int xc;
private int yc;
private int rc;
private int xr;
private int yr;
private int hr;
private int wr;
private int colorC;
private int colorR;
//default shapes
public ShapesConst(Context d) {
super(d);
xc = 200;
yc = 200;
rc = 150;
xr = 300;
yr = 300;
hr = 150;
wr = 250;
colorC = Color.BLUE;
colorR = Color.RED;
}
// circle shape
public ShapesConst(int xc, int yc, int r, int colorC, Context c) {
super(c);
this.xc = xc;
this.yc = yc;
this.rc = r;
this.colorC = colorC;
}
//rect shape
public ShapesConst(int xr, int yr, int hr, int wr, int colorR, Context rec) {
super(rec);
this.xr = xr;
this.yr = yr;
this.hr = hr;
this.wr = wr;
this.colorR = colorR;
}
//circle get
public int GetXC() {
return xc;
}
public int GetYC() {
return yc;
}
public int GetR() {
return rc;
}
public int GetColorC() {
return colorC;
}
//rect get
public int GetXR() {
return xr;
}
public int GetYR() {
return yr;
}
public int GetH() {
return hr;
}
public int GetW() {
return wr;
}
public int GetColorR() {
return colorR;
}
//circle set
public void setXC(int xc) {
this.xc = xc;
}
public void setYC(int yc) {
this.yc = yc;
}
public void setR(int r) {
this.rc = r;
}
public void setColorC(int colorC)
{
this.colorC = colorC;
}
//rect set
public void setXR(int xr) {
this.xr = xr;
}
public void setYR(int yr) {
this.yr = yr;
} public void setH(int h) {
this.hr = h;
} public void setW(int w) {
this.wr = w;
} public void setColorR(int colorR) {
this.colorR = colorR;
}
}
DrawShapes.java
public class DrawShapes extends ShapesConst {
//circle
public DrawShapes(int xc, int yc, int rc,int colorC,Context c) {
super(c);
setXC(xc);
setYC(yc);
setColorC(colorC);
setR(rc);
}
//rect
public DrawShapes(int xr, int yr, int hr, int wr, int colorR,Context r) {
super(r);
setXR(xr);
setYR(yr);
setH(hr);
setW(wr);
setColorR(colorR);
}
Paint paintC = new Paint();
Paint paintR = new Paint();
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.WHITE);
paintC.setColor(GetColorC());
paintR.setColor(GetColorR());
canvas.drawCircle(GetXC(), GetYC(), GetR(), paintC);
canvas.drawRect(GetXR(),GetYR(),GetXR()+GetYR(),GetW()+GetH(),paintR);
}
}
very bad code!
you have an onDraw method and it draws and a rectangle and a circle? seriously?
You problem here maybe you are adding one shape behind the other, you don't using the canvas element and as base you are using RelativeLayout, WHY?
Related
Following this question
RecyclerView ItemTouchHelper Buttons on Swipe
(NOT THE SAME). I would like to add buttons on each side.
The official answer from that link is for ONE side only.
What I have tried:
public abstract class SwipeHelper extends ItemTouchHelper.SimpleCallback {
public static final int BUTTON_WIDTH = 125;
private RecyclerView recyclerView;
private List<UnderlayButton> buttons;
private GestureDetector gestureDetector;
private GestureDetector gestureDetector2;
private int swipedPos = -1;
private float swipeThreshold = 0.5f;
private Map<Integer, List<UnderlayButton>> buttonsBuffer;
private Queue<Integer> recoverQueue;
private GestureDetector.SimpleOnGestureListener gestureListener = new GestureDetector.SimpleOnGestureListener(){
#Override
public boolean onSingleTapConfirmed(MotionEvent e) {
for (UnderlayButton button : buttons){
if(button.onClick(e.getX(), e.getY()))
break;
}
return true;
}
};
private GestureDetector.SimpleOnGestureListener gestureListener2 = new GestureDetector.SimpleOnGestureListener(){
#Override
public boolean onSingleTapConfirmed(MotionEvent e) {
for (UnderlayButton button : buttons){
if(button.onClick2(e.getX(), e.getY()))
break;
}
return true;
}
};
private View.OnTouchListener onTouchListener = new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent e) {
if (swipedPos < 0) return false;
Point point = new Point((int) e.getRawX(), (int) e.getRawY());
RecyclerView.ViewHolder swipedViewHolder = recyclerView.findViewHolderForAdapterPosition(swipedPos);
View swipedItem = swipedViewHolder.itemView;
Rect rect = new Rect();
swipedItem.getGlobalVisibleRect(rect);
if (e.getAction() == MotionEvent.ACTION_DOWN || e.getAction() == MotionEvent.ACTION_UP ||e.getAction() == MotionEvent.ACTION_MOVE) {
if (rect.top < point.y && rect.bottom > point.y) {
gestureDetector.onTouchEvent(e);
gestureDetector2.onTouchEvent(e);
}
//else if(rect.top > point.y && rect.bottom < point.y){ }
else {
recoverQueue.add(swipedPos);
swipedPos = -1;
recoverSwipedItem();
}
}
return false;
}
};
public SwipeHelper(Context context, RecyclerView recyclerView) {
super(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);
this.recyclerView = recyclerView;
this.buttons = new ArrayList<>();
this.gestureDetector = new GestureDetector(context, gestureListener);
this.gestureDetector2 = new GestureDetector(context, gestureListener2);
this.recyclerView.setOnTouchListener(onTouchListener);
buttonsBuffer = new HashMap<>();
recoverQueue = new LinkedList<Integer>(){
#Override
public boolean add(Integer o) {
if (contains(o))
return false;
else
return super.add(o);
}
};
attachSwipe();
}
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
int pos = viewHolder.getAdapterPosition();
if (swipedPos != pos)
recoverQueue.add(swipedPos);
swipedPos = pos;
if (buttonsBuffer.containsKey(swipedPos))
buttons = buttonsBuffer.get(swipedPos);
else
buttons.clear();
buttonsBuffer.clear();
swipeThreshold = 0.5f * buttons.size() * BUTTON_WIDTH;
recoverSwipedItem();
}
#Override
public float getSwipeThreshold(RecyclerView.ViewHolder viewHolder) {
return swipeThreshold;
}
#Override
public float getSwipeEscapeVelocity(float defaultValue) {
return 0.1f * defaultValue;
}
#Override
public float getSwipeVelocityThreshold(float defaultValue) {
return 5.0f * defaultValue;
}
#Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
int pos = viewHolder.getAdapterPosition();
float translationX = dX;
View itemView = viewHolder.itemView;
if (pos < 0){
swipedPos = pos;
return;
}
if(actionState == ItemTouchHelper.ACTION_STATE_SWIPE){
if(dX < 0) {
List<UnderlayButton> buffer = new ArrayList<>();
if (!buttonsBuffer.containsKey(pos)){
instantiateUnderlayButton(viewHolder, buffer);
buttonsBuffer.put(pos, buffer);
}
else {
buffer = buttonsBuffer.get(pos);
}
translationX = dX * buffer.size() * BUTTON_WIDTH / itemView.getWidth();
drawButtons(c, itemView, buffer, pos, translationX);
}
if(dX > 0) {
List<UnderlayButton> buffer = new ArrayList<>();
if (!buttonsBuffer.containsKey(pos)){
instantiateUnderlayButton(viewHolder, buffer);
buttonsBuffer.put(pos, buffer);
}
else {
buffer = buttonsBuffer.get(pos);
}
translationX = dX * buffer.size() * BUTTON_WIDTH / itemView.getWidth();
drawButtons(c, itemView, buffer, pos, translationX);
}
}
super.onChildDraw(c, recyclerView, viewHolder, translationX, dY, actionState, isCurrentlyActive);
}
private synchronized void recoverSwipedItem(){
while (!recoverQueue.isEmpty()){
int pos = recoverQueue.poll();
if (pos > -1) {
recyclerView.getAdapter().notifyItemChanged(pos);
}
}
}
private void drawButtons(Canvas c, View itemView, List<UnderlayButton> buffer, int pos, float dX) {
float right = itemView.getRight();
float left = itemView.getLeft();
float dButtonWidth = (-1) * dX / buffer.size();
for (UnderlayButton button : buffer) {
if (dX < 0) {
left = right - dButtonWidth;
button.onDraw(
c,
new RectF(
left,
itemView.getTop(),
right,
itemView.getBottom()
),
pos, dX
);
right = left;
} else if (dX > 0) {
right = left - dButtonWidth;
button.onDraw(c,
new RectF(
right,
itemView.getTop(),
left,
itemView.getBottom()
), pos, dX
);
left = right;
}
}
}
public void attachSwipe(){
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(this);
itemTouchHelper.attachToRecyclerView(recyclerView);
}
public abstract void instantiateUnderlayButton(RecyclerView.ViewHolder viewHolder, List<UnderlayButton> underlayButtons);
public static class UnderlayButton {
private String text;
private int imageResId;
private int color;
private UnderlayButtonClickListener clickListener;
private String text2;
private int imageResId2;
private int color2;
private UnderlayButtonClickListener2 clickListener2;
private RectF clickRegion;
private RectF clickRegion2;
private int pos;
public UnderlayButton(String text, int imageResId, int color, UnderlayButtonClickListener clickListener, String text2, int imageResId2, int color2, UnderlayButtonClickListener2 clickListener2) {
this.text = text;
this.imageResId = imageResId;
this.color = color;
this.clickListener = clickListener;
this.text2 = text2;
this.imageResId2 = imageResId2;
this.color2 = color2;
this.clickListener2 = clickListener2;
}
public boolean onClick(float x, float y){
if (clickRegion != null && clickRegion.contains(x, y)){
clickListener.onClick(pos);
return true;
}
return false;
}
public boolean onClick2(float x, float y){
if (clickRegion2 != null && clickRegion2.contains(x, y)){
clickListener2.onClick(pos);
return true;
}
return false;
}
public void onDraw(Canvas c, RectF rect, int pos, float dX) {
Paint p = new Paint();
// Draw background
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (dX < 0) {
//Boton derecho
c.drawRect(rect, p);
p.setColor(color);
}
else{
//Boton Izquierdo
p.setColor(color2);
c.drawRect(rect, p);
}
clickRegion = rect;
clickRegion2 = rect;
this.pos = pos;
}
}
}
public interface UnderlayButtonClickListener {
void onClick(int pos);
}
public interface UnderlayButtonClickListener2 {
void onClick(int pos);
}}
I tried adding more parameters to the "UnderlayButton" class because before I tried to use the two classes separately but it was throwing me problems with the OnClickListener.
So the best way I found was to add extra parameters in the "UnderlayButton" class. Still, it doesn't work for me.
Could someone help me please.
I'm a beginner android developer and trying to create a Custom Pin Edittext using the following code and i want to set the color of the pin to transparent if filled,unfortunately there is no state_filled in the attr of android, how should i do that? Help me please here is my code.
public class PinEntryEditText extends AppCompatEditText {
public static final String XML_NAMESPACE_ANDROID = "http://schemas.android.com/apk/res/android";
private float mSpace = 24; //24 dp by default, space between the lines
private float mCharSize;
private float mNumChars = 6;
private float mLineSpacing = 8; //8dp by default, height of the text from our lines
private int mMaxLength = 6;
private OnClickListener mClickListener;
private float mLineStroke = 1; //1dp by default
private float mLineStrokeSelected = 2; //2dp by default
private Paint mLinesPaint;
int[][] mStates = new int[][]{
new int[]{android.R.attr.state_selected}, // selected
new int[]{android.R.attr.state_focused}, // focused
new int[]{-android.R.attr.state_focused}, // unfocused
};
//Green color = 0xFFB6C800
//Gray color = 0xFFCCCCCC
int[] mColors = new int[]{
0xFFB6C800,
0xFFCCCCCC,
0xFF880000,
};
ColorStateList mColorStates = new ColorStateList(mStates, mColors);
public PinEntryEditText(Context context) {
super(context);
}
public PinEntryEditText(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public PinEntryEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
float multi = context.getResources().getDisplayMetrics().density;
mLineStroke = multi * mLineStroke;
mLineStrokeSelected = multi * mLineStrokeSelected;
mLinesPaint = new Paint(getPaint());
mLinesPaint.setStrokeWidth(mLineStroke);
setBackgroundResource(0);
mSpace = multi * mSpace; //convert to pixels for our density
mLineSpacing = multi * mLineSpacing; //convert to pixels for our density
mMaxLength = attrs.getAttributeIntValue(XML_NAMESPACE_ANDROID, "maxLength", 4);
mNumChars = mMaxLength;
//Disable copy paste
super.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
public void onDestroyActionMode(ActionMode mode) {
}
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
return false;
}
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return false;
}
});
// When tapped, move cursor to end of text.
super.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
setSelection(getText().length());
if (mClickListener != null) {
mClickListener.onClick(v);
}
}
});
}
#Override
public void setOnClickListener(OnClickListener l) {
mClickListener = l;
}
#Override
public void setCustomSelectionActionModeCallback(ActionMode.Callback actionModeCallback) {
throw new RuntimeException("setCustomSelectionActionModeCallback() not supported.");
}
#Override
protected void onDraw(Canvas canvas) {
//super.onDraw(canvas);
int availableWidth = getWidth() - getPaddingRight() - getPaddingLeft();
if (mSpace < 0) {
mCharSize = (availableWidth / (mNumChars * 2 - 1));
} else {
mCharSize = (availableWidth - (mSpace * (mNumChars - 1))) / mNumChars;
}
int startX = getPaddingLeft();
int bottom = getHeight() - getPaddingBottom();
//Text Width
Editable text = getText();
int textLength = text.length();
float[] textWidths = new float[textLength];
getPaint().getTextWidths(getText(), 0, textLength, textWidths);
for (int i = 0; i < mNumChars; i++) {
updateColorForLines(i == textLength);
canvas.drawLine(startX, bottom, startX + mCharSize, bottom, mLinesPaint);
if (getText().length() > i) {
float middle = startX + mCharSize / 2;
canvas.drawText(text, i, i + 1, middle - textWidths[0] / 2, bottom - mLineSpacing, getPaint());
}
if (mSpace < 0) {
startX += mCharSize * 2;
} else {
startX += mCharSize + mSpace;
}
}
//mLinesPaint.setColor(getColorForState(0xff1a1f71));
}
private int getColorForState(int... states) {
return mColorStates.getColorForState(states, Color.GRAY);
}
/**
* #param next Is the current char the next character to be input?
*/
private void updateColorForLines(boolean next) {
if (isFocused()) {
mLinesPaint.setStrokeWidth(mLineStrokeSelected);
mLinesPaint.setColor(getColorForState(android.R.attr.state_focused));
if (next) {
mLinesPaint.setColor(getColorForState(android.R.attr.state_selected));
}
} else {
mLinesPaint.setStrokeWidth(mLineStroke);
mLinesPaint.setColor(getColorForState(-android.R.attr.state_focused));
}
}
}
Is there a way to do it?
there is no state_filled but you can create one. you can use TextWatcher interface it will be triggered whenever text will be updated. you can check there if current text size is equal to your mMaxLength set your pin color to transparent or else.
here is an example of TextWatcher implementation :
et1.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
});
i cannot move a custom view with this code :
Ball.java
public class Ball extends View {
int x, y;
public Ball(Context context) {
super(context);
}
public void setSizes( int x, int y) {
this.x = x;
this.y = y;
}
protected void onDraw(Canvas c) {
Paint paint = new Paint();
paint.setColor(Color.BLACK);
int radius = 50;
c.drawCircle(x,y,radius,paint);
}
}
BounceLoop.java
public class BounceLoop extends Thread {
int width, height, x, y;
boolean jumping = false;
public void setSizes(int width, int height) {
this.width = width;
this.height = height;
}
public void run() {
jumping = true;
x = 0;
y = 0;
while(jumping) {
}
}
}
and MyActivity.java
public class MyActivity extends Activity {
RelativeLayout content;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
content = (RelativeLayout) findViewById(R.id.content);
BounceLoop thread = new BounceLoop();
thread.setSizes(content.getWidth(), content.getHeight());
thread.start();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.my, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
How do i move the ball from the BounceLoop thread ? I don't want to do it with AsyncTask, do i have to use handlers or ?
your thread will probably need a reference of your custom view and in the run() I would have expected something like
public void run() {
jumping = true;
x = 0;
y = 0;
while(jumping) {
mCircleView.setPosition(newX, newY);
mCircleView.postInvalidate();
}
}
be aware that you can't touch the UI Through another thread, this is way I called postInvalidate() instead of invalidate(). The former will reschedule a draw event on the UI Thread
Finally i did this :
public class MyActivity extends Activity {
RelativeLayout content;
Handler myHandler;
Ball view;
Thread loop;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
content = (RelativeLayout) findViewById(R.id.content);
view = new Ball(this);
view.setPosition(50, 50);
content.addView(view);
myHandler = new Handler() {
public void handleMessage(Message msg) {
int x = (int) msg.arg1;
int y = (int) msg.arg2;
Log.d("ss", String.valueOf(x));
view.setPosition(x, y);
}
};
}
public void onWindowFocusChanged(boolean hasChanged) {
super.onWindowFocusChanged(hasChanged);
loop = new Thread(new Runnable() {
#Override
public void run() {
int x = 0;
int y = 0;
Log.d("width", String.valueOf(view.getWidth()));
while (x < content.getWidth() - view.radius) {
x += 5;
y += 7;
Message msg = new Message();
msg.arg1 = x;
msg.arg2 = y;
myHandler.sendMessage(msg);
try {
Thread.sleep(25);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
loop.start();
}
}
but this is not comfortable for me to have the thread in the activity, how can i export it to another class...
I'm currently implementing my own custom listview. I idea is that a longclick on a list item will scale the surrounding visible views to a smaller value scale and leave the the current view normal, whilst expanding a view below the current selected view. Once the user touches anywhere around the selected view, it will scale everything back to normal.
Unfortunately, there's an issue whereby the last view maybe partially hidden during the scale animation and so doesn't scale back to normal. So when you try to gain focus to the rest of the Listview by touching outside the selected list item, it remains a smaller scale.
I've tried a few approaches, from using ViewTreeObserver to storing the positions of the list items to make sure that they get scaled, but nothing has worked. Below is my custom listview:
public class ZoomListView extends ListView implements AdapterView.OnItemLongClickListener {
private static final String TAG = ZoomListView.class.getName();
private int _xPos;
private int _yPos;
private int _pointerId;
private Rect _viewBounds;
private boolean _isZoomed;
private OnItemClickListener _listner;
private OnItemFocused _onItemFocusedLis;
private int _expandingViewHeight = 0;
private int _previousFocusedViewHeight;
public interface OnItemFocused {
/**
* This interface can be used to be notified when a particular item should be disabled, or is currently not focused
* #param position
*/
public void onItemOutOfFocus(int position, boolean status_);
public View onItemFocused(View focusedView_, int listViewPosition_, long uniqueId_);
}
public ZoomListView(Context context_) {
super(context_);
init(context_);
}
public ZoomListView(Context context_, AttributeSet attrs) {
super(context_, attrs);
init(context_);
}
public ZoomListView(Context context_, AttributeSet attrs, int defStyle) {
super(context_, attrs, defStyle);
init(context_);
}
#Override
public void setOnItemClickListener(OnItemClickListener listener) {
if(!(listener == null)){
_listner = listener;
}
super.setOnItemClickListener(listener);
}
private void init(Context context_){
setOnItemLongClickListener(this);
}
public void setOnItemDisableListener(OnItemFocused listener_){
_onItemFocusedLis = listener_;
}
private void scaleChildViews(long rowId_, int itemPos_, float scale, boolean shouldEnable){
if (_isZoomed) {
getParent().requestDisallowInterceptTouchEvent(true);
}
int firstVisiblePosition = getFirstVisiblePosition();
int pos = pointToPosition(_xPos, _yPos);
int positionOrg = pos - firstVisiblePosition;
scaleAllVisibleViews(positionOrg, scale, shouldEnable);
}
private void scaleAllVisibleViews(final int clickedItemPosition_, final float scale_, final boolean shouldEnable_) {
Animation scaleAnimation;
if(_isZoomed){
scaleAnimation = getZoomAnimation(1f, 0.8f, 1f, 0.8f);
}else{
scaleAnimation = getZoomAnimation(0.8f, 1f, 0.8f, 1f);
}
int firstVisiblePosition = getFirstVisiblePosition();
int count = getChildCount();
for (int i = 0; i < count; i++) {
int pos = i;
if (_isZoomed) {
if (getAdapter().getItemId(clickedItemPosition_) != getAdapter().getItemId(pos)) {
scaleView(pos, scale_, shouldEnable_, scaleAnimation);
}else{
displayExpandingView(pos, clickedItemPosition_);
}
} else {
View view = getChildAt(pos);
View viewToShow = _onItemFocusedLis.onItemFocused(view, pos, getAdapter().getItemId(clickedItemPosition_));
if(viewToShow != null){
viewToShow.setVisibility(GONE);
}
scaleView(pos, scale_, shouldEnable_, scaleAnimation);
}
}
}
private void displayExpandingView(int position_, int clickedItemPosition_){
View view = getChildAt(position_);
if(view != null){
Log.v(TAG, "view is valid");
View viewToShow = _onItemFocusedLis.onItemFocused(view, position_, getAdapter().getItemId(clickedItemPosition_));
viewToShow.setVisibility(VISIBLE);
Animation flip = new CyclicFlipAnimation(50f);
flip.setDuration(500);
viewToShow.startAnimation(flip);
if(_expandingViewHeight <= 0){
viewToShow.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
_expandingViewHeight = viewToShow.getMeasuredHeight();
Log.v(TAG, "expanding view hieght is + " + _expandingViewHeight);
}
}
}
private Animation getZoomAnimation(float fromX_, float toX_, float fromY_, float toY_){
Animation scaleAnimation = new ScaleAnimation(
fromX_, toX_,
fromY_, toY_,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setFillAfter(true);
scaleAnimation.setDuration(500);
return scaleAnimation;
}
private void scaleView(int position_, float scale_, boolean shouldEnable_, Animation animation_){
View view = getChildAt(position_);
if (view != null) {
view.startAnimation(animation_);
if (_onItemFocusedLis != null) {
_onItemFocusedLis.onItemOutOfFocus(position_, shouldEnable_);
}
}
}
#Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
_isZoomed = true;
scaleChildViews(l, i, 0.8f, false);
return true;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
_xPos = (int) event.getX();
_yPos = (int) event.getY();
_pointerId = event.getPointerId(0);
if (_isZoomed) {
if (!_viewBounds.contains(_xPos, _yPos)) {
_isZoomed = false;
scaleChildViews(1, 1, 1f, true);
}
return false;
}
int position = pointToPosition(_xPos, _yPos);
int childNum = (position != INVALID_POSITION) ? position - getFirstVisiblePosition() : -1;
View itemView = (childNum >= 0) ? getChildAt(childNum) : null;
if (itemView != null) {
_viewBounds = getChildViewRect(this, itemView);
}
break;
}
return super.onTouchEvent(event);
}
private Rect getChildViewRect(View parentView, View childView) {
final Rect childRect = new Rect(childView.getLeft(), childView.getTop(), childView.getRight(), childView.getBottom() + _expandingViewHeight);
if (parentView == childView) {
return childRect;
}
ViewGroup parent = (ViewGroup) childView.getParent();
while (parent != parentView) {
childRect.offset(parent.getLeft(), parent.getTop());
childView = parent;
parent = (ViewGroup) childView.getParent();
}
return childRect;
}
}
Any idea's on what maybe wrong, thanks.
To fix this issue I ended up adding a ACTION_MOVE case statement in my onTouch method. So as long as the list items were focused again, when the list performed a move i.e. scrolled the list item, the remaining list items are restored to their original size. To achieve this you need to maintain a map/collection of id's that correspond to your list items and iterate over them once the user scrolls.
Heres the full somwhat functiong implementation:
package com.sun.tweetfiltrr.zoomlistview;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import com.sun.tweetfiltrr.animation.CyclicFlipAnimation;
import java.util.HashMap;
import java.util.Map;
/**
*/
public class ZoomListView extends ListView implements AdapterView.OnItemLongClickListener {
private static final String TAG = ZoomListView.class.getName();
private int _xPos;
private int _yPos;
private int _pointerId;
private Rect _viewBounds;
private boolean _isZoomed;
private OnItemClickListener _listner;
private OnItemFocused _onItemFocusedLis;
private int _expandingViewHeight = 0;
private int _previousFocusedViewHeight;
private OnScrollListener _onScrollListener;
private boolean _shouldPerformScrollAnimation;
final private Map<Long, PropertyHolder> _itemIDToProperty = new HashMap<Long, PropertyHolder>();
private long _currentFocusedId;
public interface OnItemFocused {
/**
* This interface can be used to be notified when a particular item should be disabled, or is currently not focused
* #param position
*/
public void onItemScaleOut(int position, View view, boolean status_);
public void onItemRestore(int position, View view, boolean status_);
public View onItemFocused(View focusedView_, int listViewPosition_, long uniqueId_);
}
public ZoomListView(Context context_) {
super(context_);
init(context_);
}
public ZoomListView(Context context_, AttributeSet attrs) {
super(context_, attrs);
init(context_);
}
public ZoomListView(Context context_, AttributeSet attrs, int defStyle) {
super(context_, attrs, defStyle);
init(context_);
}
private void init(Context context_){
setOnItemLongClickListener(this);
}
public void setOnItemDisableListener(OnItemFocused listener_){
_onItemFocusedLis = listener_;
}
private void scaleChildViews(long rowId_, int itemPos_, float scale, boolean shouldEnable){
if (_isZoomed) {
getParent().requestDisallowInterceptTouchEvent(true);
}
scaleAllVisibleViews(shouldEnable);
}
private void scaleAllVisibleViews(final boolean shouldEnable_) {
final ListAdapter adapter = getAdapter();
Animation scaleAnimation;
if(_isZoomed){
scaleAnimation = getZoomAnimation(1f, 0.6f, 1f, 0.6f);
}else{
scaleAnimation = getZoomAnimation(0.6f, 1f, 0.6f, 1f);
}
int count = getChildCount();
for (int i = 0; i < count; i++) {
applyAnimation(i, adapter, shouldEnable_, scaleAnimation);
}
}
private void applyAnimation(int position_, ListAdapter adapter_, boolean shouldEnable_, Animation animation_){
if (_isZoomed) {
if (_currentFocusedId != adapter_.getItemId(position_)) {
scaleView(position_, shouldEnable_, animation_);
}else{
displayExpandingView(position_, adapter_);
}
}else{
if(_currentFocusedId != getAdapter().getItemId(position_)){
scaleView(position_, shouldEnable_, animation_);
}else{
View view = getChildAt(position_);
View viewToShow = _onItemFocusedLis.onItemFocused(view, position_, getAdapter().getItemId(position_));
if(viewToShow != null){
viewToShow.setVisibility(GONE);
}
}
_itemIDToProperty.remove(getAdapter().getItemId(position_));
}
}
private void displayExpandingView(int position_, ListAdapter adapter_){
View view = getChildAt(position_);
if(view != null){
View viewToShow = _onItemFocusedLis.onItemFocused(view, position_, adapter_.getItemId(position_));
viewToShow.setVisibility(VISIBLE);
Animation flip = new CyclicFlipAnimation(60f);
flip.setDuration(1000);
viewToShow.startAnimation(flip);
if(_expandingViewHeight <= 0){
viewToShow.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
_expandingViewHeight = viewToShow.getMeasuredHeight();
}
}
}
private Animation getZoomAnimation(float fromX_, float toX_, float fromY_, float toY_){
Animation scaleAnimation = new ScaleAnimation(
fromX_, toX_,
fromY_, toY_,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.ABSOLUTE, 0.7f);
scaleAnimation.setFillAfter(true);
scaleAnimation.setDuration(500);
return scaleAnimation;
}
private void scaleView(int position_, boolean shouldEnable_, Animation animationScale_ ){
View view = getChildAt(position_);
ListAdapter adapter = getAdapter();
long id = adapter.getItemId(position_);
view.startAnimation(animationScale_);
PropertyHolder holder = _itemIDToProperty.get(id);
if (holder == null) {
holder = new PropertyHolder((int) view.getTop(), (int) (view.getBottom()));
_itemIDToProperty.put(id, holder);
}
int h = view.getHeight();
if (_isZoomed) {
view.animate().translationYBy((h * 0.5f)).setDuration(500).start();
if (_onItemFocusedLis != null) {
_onItemFocusedLis.onItemScaleOut(position_, view, shouldEnable_);
}
} else {
view.animate().translationYBy(-(h * 0.5f )).setDuration(500).start();
if (_onItemFocusedLis != null) {
_onItemFocusedLis.onItemRestore(position_, view, shouldEnable_);
}
}
}
#Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
_isZoomed = true;
int firstVisiblePosition = getFirstVisiblePosition();
int pos = pointToPosition(_xPos, _yPos);
int positionOrg = pos - firstVisiblePosition;
_currentFocusedId = getAdapter().getItemId(positionOrg);
scaleChildViews(l, i, 0.8f, false);
return true;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
_xPos = (int) event.getX();
_yPos = (int) event.getY();
_pointerId = event.getPointerId(0);
if (_isZoomed) {
if (!_viewBounds.contains(_xPos, _yPos)) {
_isZoomed = false;
scaleChildViews(1, 1, 1f, true);
}
return false;
}
int position = pointToPosition(_xPos, _yPos);
int childNum = (position != INVALID_POSITION) ? position - getFirstVisiblePosition() : -1;
View itemView = (childNum >= 0) ? getChildAt(childNum) : null;
if (itemView != null) {
_viewBounds = getChildViewRect(this, itemView);
}
break;
case MotionEvent.ACTION_MOVE:
if (!_isZoomed) {
animateRemaining();
}
break;
}
return super.onTouchEvent(event);
}
private void animateRemaining(){
if(!_itemIDToProperty.isEmpty()){
for(int i = 0; i < getChildCount(); i++){
long id = getAdapter().getItemId(i);
PropertyHolder n = _itemIDToProperty.get(id);
if(n != null){
if(_currentFocusedId != getAdapter().getItemId(i)){
scaleView(i, true, getZoomAnimation(0.6f, 1, 0.6f, 1f));
}else{
Log.v(TAG, "not translating for " + getAdapter().getItemId(i)+ " for id " + _currentFocusedId);
}
_itemIDToProperty.remove(id);
}
}
}
}
private Rect getChildViewRect(View parentView, View childView) {
final Rect childRect = new Rect(childView.getLeft(), childView.getTop(), childView.getRight(), childView.getBottom() + _expandingViewHeight);
if (parentView == childView) {
return childRect;
}
ViewGroup parent = (ViewGroup) childView.getParent();
while (parent != parentView) {
childRect.offset(parent.getLeft(), parent.getTop());
childView = parent;
parent = (ViewGroup) childView.getParent();
}
return childRect;
}
private class PropertyHolder{
int _top;
int _bot;
private PropertyHolder(int top_, int bot_){
_top = top_;
_bot = bot_;
}
}
}
It's far from perfect but its a starting point.
I would like to include a color picker in my paint program. So anyone here has already done something like this please give me some tutorials or piece of code to get me started. I really need to get the whole idea of adding this. I already have set up the canvas for the drawing so I'd like to add the color picker to it. Any ideas are welcome. Thanks.
Your class should implement ColorPickerDialog.OnColorChangedListener
public class MainActivity implements ColorPickerDialog.OnColorChangedListener
{
private Paint mPaint;
mPaint = new Paint();
// on button click
new ColorPickerDialog(this, this, mPaint.getColor()).show();
}
ColorPicker Dialog
public class ColorPickerDialog extends Dialog {
public interface OnColorChangedListener {
void colorChanged(int color);
}
private OnColorChangedListener mListener;
private int mInitialColor;
private static class ColorPickerView extends View {
private Paint mPaint;
private Paint mCenterPaint;
private final int[] mColors;
private OnColorChangedListener mListener;
ColorPickerView(Context c, OnColorChangedListener l, int color) {
super(c);
mListener = l;
mColors = new int[] {
0xFFFF0000, 0xFFFF00FF, 0xFF0000FF, 0xFF00FFFF, 0xFF00FF00,
0xFFFFFF00, 0xFFFF0000
};
Shader s = new SweepGradient(0, 0, mColors, null);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setShader(s);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(32);
mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mCenterPaint.setColor(color);
mCenterPaint.setStrokeWidth(5);
}
private boolean mTrackingCenter;
private boolean mHighlightCenter;
#Override
protected void onDraw(Canvas canvas) {
float r = CENTER_X - mPaint.getStrokeWidth()*0.5f;
canvas.translate(CENTER_X, CENTER_X);
canvas.drawOval(new RectF(-r, -r, r, r), mPaint);
canvas.drawCircle(0, 0, CENTER_RADIUS, mCenterPaint);
if (mTrackingCenter) {
int c = mCenterPaint.getColor();
mCenterPaint.setStyle(Paint.Style.STROKE);
if (mHighlightCenter) {
mCenterPaint.setAlpha(0xFF);
} else {
mCenterPaint.setAlpha(0x80);
}
canvas.drawCircle(0, 0,
CENTER_RADIUS + mCenterPaint.getStrokeWidth(),
mCenterPaint);
mCenterPaint.setStyle(Paint.Style.FILL);
mCenterPaint.setColor(c);
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(CENTER_X*2, CENTER_Y*2);
}
private static final int CENTER_X = 100;
private static final int CENTER_Y = 100;
private static final int CENTER_RADIUS = 32;
private int floatToByte(float x) {
int n = java.lang.Math.round(x);
return n;
}
private int pinToByte(int n) {
if (n < 0) {
n = 0;
} else if (n > 255) {
n = 255;
}
return n;
}
private int ave(int s, int d, float p) {
return s + java.lang.Math.round(p * (d - s));
}
private int interpColor(int colors[], float unit) {
if (unit <= 0) {
return colors[0];
}
if (unit >= 1) {
return colors[colors.length - 1];
}
float p = unit * (colors.length - 1);
int i = (int)p;
p -= i;
// now p is just the fractional part [0...1) and i is the index
int c0 = colors[i];
int c1 = colors[i+1];
int a = ave(Color.alpha(c0), Color.alpha(c1), p);
int r = ave(Color.red(c0), Color.red(c1), p);
int g = ave(Color.green(c0), Color.green(c1), p);
int b = ave(Color.blue(c0), Color.blue(c1), p);
return Color.argb(a, r, g, b);
}
private int rotateColor(int color, float rad) {
float deg = rad * 180 / 3.1415927f;
int r = Color.red(color);
int g = Color.green(color);
int b = Color.blue(color);
ColorMatrix cm = new ColorMatrix();
ColorMatrix tmp = new ColorMatrix();
cm.setRGB2YUV();
tmp.setRotate(0, deg);
cm.postConcat(tmp);
tmp.setYUV2RGB();
cm.postConcat(tmp);
final float[] a = cm.getArray();
int ir = floatToByte(a[0] * r + a[1] * g + a[2] * b);
int ig = floatToByte(a[5] * r + a[6] * g + a[7] * b);
int ib = floatToByte(a[10] * r + a[11] * g + a[12] * b);
return Color.argb(Color.alpha(color), pinToByte(ir),
pinToByte(ig), pinToByte(ib));
}
private static final float PI = 3.1415926f;
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX() - CENTER_X;
float y = event.getY() - CENTER_Y;
boolean inCenter = java.lang.Math.sqrt(x*x + y*y) <= CENTER_RADIUS;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mTrackingCenter = inCenter;
if (inCenter) {
mHighlightCenter = true;
invalidate();
break;
}
case MotionEvent.ACTION_MOVE:
if (mTrackingCenter) {
if (mHighlightCenter != inCenter) {
mHighlightCenter = inCenter;
invalidate();
}
} else {
float angle = (float)java.lang.Math.atan2(y, x);
// need to turn angle [-PI ... PI] into unit [0....1]
float unit = angle/(2*PI);
if (unit < 0) {
unit += 1;
}
mCenterPaint.setColor(interpColor(mColors, unit));
invalidate();
}
break;
case MotionEvent.ACTION_UP:
if (mTrackingCenter) {
if (inCenter) {
mListener.colorChanged(mCenterPaint.getColor());
}
mTrackingCenter = false; // so we draw w/o halo
invalidate();
}
break;
}
return true;
}
}
public ColorPickerDialog(Context context,
OnColorChangedListener listener,
int initialColor) {
super(context);
mListener = listener;
mInitialColor = initialColor;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
OnColorChangedListener l = new OnColorChangedListener() {
public void colorChanged(int color) {
mListener.colorChanged(color);
dismiss();
}
};
setContentView(new ColorPickerView(getContext(), l, mInitialColor));
setTitle("Pick a Color");
}
You have to choose the color and click the center circle to pick the color. Set the color to your paint object and use the same to draw.
Snap shot
Edit 2:
Source code can be found at https://code.google.com/p/android-color-picker/
Another ColorPickerDialog
public class ColorPickerDialog extends AlertDialog implements
ColorPickerView.OnColorChangedListener {
private ColorPickerView mColorPicker;
private ColorPanelView mOldColor;
private ColorPanelView mNewColor;
private OnColorChangedListener mListener;
public ColorPickerDialog(Context myDrawingMenuOptionEventsListener, int initialColor) {
super(myDrawingMenuOptionEventsListener);
init(initialColor);
}
private void init(int color) {
// To fight color branding.
getWindow().setFormat(PixelFormat.RGBA_8888);
setUp(color);
}
private void setUp(int color) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.dialog_color_picker, null);
layout.setBackgroundColor(Color.WHITE);
setView(layout);
setTitle("Choose a Color");
// setIcon(android.R.drawable.ic_dialog_info);
mColorPicker = (ColorPickerView) layout
.findViewById(R.id.color_picker_view);
mOldColor = (ColorPanelView) layout.findViewById(R.id.old_color_panel);
mNewColor = (ColorPanelView) layout.findViewById(R.id.new_color_panel);
((LinearLayout) mOldColor.getParent()).setPadding(Math
.round(mColorPicker.getDrawingOffset()), 0, Math
.round(mColorPicker.getDrawingOffset()), 0);
mColorPicker.setOnColorChangedListener(this);
mOldColor.setColor(color);
mColorPicker.setColor(color, true);
}
#Override
public void onColorChanged(int color) {
mNewColor.setColor(color);
if (mListener != null) {
mListener.onColorChanged(color);
}
}
public void setAlphaSliderVisible(boolean visible) {
mColorPicker.setAlphaSliderVisible(visible);
}
public int getColor() {
return mColorPicker.getColor();
}
}
Usage :
final ColorPickerDialog d= new ColorPickerDialog(ActivityName.this,0xffffffff);
d.setAlphaSliderVisible(true);
d.setButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
mPaint.setColor(d.getColor());
}
});
d.setButton2("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
});
d.show();
Snap shot:
In the above choose the color on the right bar. You also make a choice how dark or light the color choosen should be. Click ok to set the paint to your paint object and use the same to draw. Cancel will dismiss the color picker dialog.
Edit 3:
Only change instead of clear function i have added color picker on click of clear button.
public class MainActivity extends Activity implements ColorPickerDialog.OnColorChangedListener {
DrawingView dv ;
RelativeLayout rl;
private Paint mPaint;
private MaskFilter mEmboss;
private MaskFilter mBlur;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dv = new DrawingView(this);
setContentView(R.layout.activity_main);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.GREEN);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
rl = (RelativeLayout) findViewById(R.id.rl);
rl.addView(dv);
Button b = (Button) findViewById(R.id.button1);
//b.setText(R.string.France);
Button b1 = (Button) findViewById(R.id.button2);
rl.setDrawingCacheEnabled(true);
b.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
// dv.clear();
new ColorPickerDialog(MainActivity.this, MainActivity.this, mPaint.getColor()).show();
}
});
b1.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
AlertDialog.Builder editalert = new AlertDialog.Builder(MainActivity.this);
editalert.setTitle("Please Enter the name with which you want to Save");
final EditText input = new EditText(MainActivity.this);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.FILL_PARENT);
input.setLayoutParams(lp);
editalert.setView(input);
editalert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
rl.setDrawingCacheEnabled(true);
String name= input.getText().toString();
Bitmap bitmap =rl.getDrawingCache();
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/MyDraw");
myDir.mkdirs();
File file = new File (myDir, name+".png");
if (file.exists ()) file.delete ();
try
{
if(!file.exists())
{
file.createNewFile();
}
FileOutputStream ostream = new FileOutputStream(file);
bitmap.compress(CompressFormat.PNG, 10, ostream);
// System.out.println("saving......................................................"+path);
ostream.close();
rl.invalidate();
}
catch (Exception e)
{
e.printStackTrace();
}finally
{
rl.setDrawingCacheEnabled(false);
}
}
});
editalert.show();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public class DrawingView extends View {
private static final float MINP = 0.25f;
private static final float MAXP = 0.75f;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
Context context;
private Paint circlePaint;
private Path circlePath;
public DrawingView(Context c) {
super(c);
context=c;
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
circlePaint = new Paint();
circlePath = new Path();
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.BLUE);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setStrokeJoin(Paint.Join.MITER);
circlePaint.setStrokeWidth(4f);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
canvas.drawPath(circlePath, circlePaint);
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
mX = x;
mY = y;
circlePath.reset();
circlePath.addCircle(mX, mY, 30, Path.Direction.CW);
invalidate();
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
circlePath.reset();
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath.reset();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
}
#Override
public void colorChanged(int color) {
// TODO Auto-generated method stub
mPaint.setColor(color);
}
}
you have a google code which can help you
http://code.google.com/p/android-color-picker/
I used this link for color picker http://code.google.com/p/android-color-picker/
steps:
I've added some extra file(like:"android-mvn-push.gradle" ) you can skip that file in step 3
and also remove this "apply from: '../android-mvn-push.gradle' " from your bulid.gradle(Module:liabrary) file if your skipping step 3.
Go to the above link and download project as zip file and extract the zip.
Inside Extracted folder you'll see library folder.
Copy that folder into your android Applications main folder where it contains all its gradle n all... and also copy "android-mvn-push.gradle" file to your main project folder.
open bulid.gradle(Module:app) inside that add dependencies like this,
"compile project(':library')"
update Settings.Gradle with include ':app', ':library'
go to Tools>Android>Sync with Gradles and then it will show some error like build gradle not matching bla bla....
Click on that open file error option.
In your bulid.gradle(Module:liabrary) change this,
apply plugin: 'com.android.library'
android {
compileSdkVersion propCompileSdkVersion
buildToolsVersion propBuildToolsVersion
defaultConfig {
minSdkVersion propMinSdkVersion
targetSdkVersion propTargetSdkVersion
versionCode propVersionCode
versionName propVersionName
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
apply from: '../android-mvn-push.gradle'
To>>>>>>>>>>>
apply plugin: 'com.android.library'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
minSdkVersion 14
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
apply from: '../android-mvn-push.gradle'
Finally Tools>Android > Sync with gradle...
and Bingo....It Works ....!!!