Reputation: 2745
I'm using this app to draw free lines in android
DrawerView.java
public class DrawerView extends View {
public static Paint paint;
Paint paint2 = new Paint();
public Path path = new Path();
public Path circlePath = new Path();
public static int lineCol = Color.BLUE;
public static boolean isTouchable = false;
public LayoutParams params;
public DrawerView(Context context, AttributeSet attrs){
super(context, attrs);
paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(lineCol);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(4f);
}
public void onButtonPress(){
// resets the screen
path.reset();
// Calls the onDraw() method
postInvalidate();
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawPath(path, paint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isTouchable){
return false;
} else {
// Gives you x and y coordinates on the Event.
float pointX = event.getX();
float pointY = event.getY();
// Checks for the event that occurs
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
path.moveTo(pointX, pointY);
return true;
case MotionEvent.ACTION_MOVE:
path.lineTo(pointX, pointY);
circlePath.reset();
circlePath.addCircle(pointX, pointY, 30, Path.Direction.CW);
break;
case MotionEvent.ACTION_UP:
circlePath.reset();
break;
default:
return false;
}
postInvalidate();
return true;
}
}
}
DrawLines.java
public class DrawLines extends Activity {
DrawerView myView;
public Button btnReset;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.draw_line);
myView = (DrawerView)findViewById(R.id.custView);
btnReset = (Button) findViewById(R.id.button1);
btnReset.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
// resets the screen
myView.path.reset();
// Calls the onDraw() method
myView.postInvalidate();
}
});
}
}
draw_line.xml
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Clear" />
<com.example.drawline.DrawerView
android:id="@+id/custView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/button1"
android:layout_margin="5dp"
custom:lineColor="#ff0099" />
It works well with me but I want to be able to select the color of line, so I added a button in draw_line.xml that when press it show a dialog that asks the user to select color. this is the code of dialog
public void openSelectColorDialog()
{
final Dialog d = new Dialog(this);
d.setTitle("Select Color");
d.setContentView(R.layout.military_list);
int image[] = { R.drawable.black, R.drawable.blue, R.drawable.yellow};
ArrayList<HashMap<String, String>> objArayList = new ArrayList<HashMap<String, String>>();
for (int i = 0; i < image.length; i++) {
HashMap<String, String> listData = new HashMap<String, String>();
listData.put("image", Integer.toString(image[i]));
objArayList.add(listData);
}
String[] from = { "image"};
int[] to = { R.id.list_image };
SimpleAdapter listAdapter = new SimpleAdapter(this, objArayList,
R.layout.military_list_item, from, to);
ListView lst1 = (ListView) d.findViewById(android.R.id.list);
lst1.setAdapter(listAdapter);
lst1.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parentView, View childView, int position, long id) {
if (position == 0) {
// the code of color line
d.dismiss();
} else if (position == 1) {
// the code of blue line
d.dismiss();
} else {
// the code of yellow line
d.dismiss();
}
myView.postInvalidate();
}
});
d.show();
}
What is the code I have to add to make the color like what I selected ?
consider if I write this code DrawerView.paint.setColor(Color.BLACK); the whole line changes its color to the selected color and this is not what I want. I want that the color of the new line is like what I selected and keep the old lines with its colors.
Hope anyone got my mean.
Thanks in advance.
Edit
the new code is: ColoredPath.java
public class ColoredPath {
private Paint paint;
private Path path = new Path();
private int color;
public ColoredPath() {
paint = new Paint();
color = Color.BLACK;
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(4f);
paint.setAntiAlias(true);
paint.setColor(color);
}
public ColoredPath(int color) {
paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(4f);
paint.setAntiAlias(true);
paint.setColor(color);
}
public void setColor(int color){
this.color = color;
}
public int getColor(){
return color;
}
public void setPaint(Paint paint){
this.paint = paint;
}
public Paint getPaint() {
return paint;
}
public void setPath(Path path){
this.path = path;
}
public Path getPath() {
return path;
}
}
DrawerView.java
public class DrawerView extends View {
public Path circlePath = new Path();
public static int LINE_COLOR = 0;
public static boolean isTouchable = false;
public List<ColoredPath> paths = new ArrayList<ColoredPath>();
public ColoredPath currentPath;
public DrawerView(Context context, AttributeSet attrs){
super(context, attrs);
currentPath = new ColoredPath();
paths.add(currentPath);
}
public void newLine(int color){
System.out.println("in newLine method");
currentPath = new ColoredPath(color);
paths.add(currentPath);
//postInvalidate();
}
public void onButtonPress(){
// resets the screen
currentPath.getPath().reset();
// Calls the onDraw() method
postInvalidate();
}
@Override
protected void onDraw(Canvas canvas) {
System.out.println("size of paths: "+paths.size());
canvas.drawPath(currentPath.getPath(), currentPath.getPaint());
for(int i = 0; i < paths.size(); ++i) {
//ColoredPath coloredPath = paths.get(i);
canvas.drawPath(currentPath.getPath(), currentPath.getPaint());
}
}
public Path getLastPath() {
Path path = new Path();
for(int i = 0; i < paths.size(); ++i) {
path.addPath(paths.get(i).getPath());
}
return path;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isTouchable){
return false;
} else {
// Gives you x and y coordinates on the Event.
float pointX = event.getX();
float pointY = event.getY();
// Checks for the event that occurs
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
currentPath.getPath().moveTo(pointX, pointY);
//getLastPath().moveTo(pointX, pointY);
return true;
case MotionEvent.ACTION_MOVE:
currentPath.getPath().lineTo(pointX, pointY);
//getLastPath().lineTo(pointX, pointY);
circlePath.reset();
circlePath.addCircle(pointX, pointY, 30, Path.Direction.CW);
break;
case MotionEvent.ACTION_UP:
circlePath.reset();
break;
default:
return false;
}
postInvalidate();
return true;
}
}
}
and in MainActivity.java
if (position == 1) {
// blue
myView.newLine(Color.BLUE);
d.dismiss();
}
this works well and colors the lines but when I select any color it leads to remove the last line and I want all lines with there colors.
Upvotes: 1
Views: 3365
Reputation: 2303
Because Path itself doesn't contain any information about it's color (color is managed by Canvas) I would suggest you to create new pair of (Path, Paint) for every new path with different paint and use only current pair in onTouch event. So here is some code which illustrate this idea
public class ColoredPath {
private Paint paint;
private Path path;
public ColoredPath(Paint paint, Path path) {
this.paint = paint;
this.path = path;
}
public Paint getPaint() {
return paint;
}
public Path getPath() {
return path;
}
}
private List<ColoredPath> paths = new ArrayList<ColoredPath>();
public DrawerView(Context context, AttributeSet attrs){
super(context, attrs);
//custom paint can be used here
paths.add(new ColoredPath(new Paint(), new Path()));
}
/////
@Override
protected void onDraw(Canvas canvas) {
for(ColoredPath coloredPath : paths) {
canvas.drawPath(coloredPath.getPath(), coloredPath.getPaint());
}
}
Where paths is List<ColoredPath>
. And also you need field like ColoredPath currentPath
.
Upvotes: 1