I have a project where I need a custom canvas (white sheet) like a view.
The activity will have two divisions
The aforementioned canvas.
A list/recycler view with images (ignore the temporary LinearLayout instead of list/recycler view)
So when I click on an Image. This image will get transferred to the canvas. Where user can drag, scale, rotate or do all of these together to that image. This canvas should support up to 4-5 images at the same time.
I would like to know if there is any better alternative or I am going to the right direction.
If I am going to the right direction. Please help me on this issue.
A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x180 in tid 18318 (odrob_sylvester)
Here is my Activity Class (CanvasActivity.java)
public class CanvasActivity extends AppCompatActivity {
private static final String TAG = CanvasActivity.class.getSimpleName();
private WodrobView canvas;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_canvas);
canvas = (WodrobView) findViewById(R.id.canvas);
}
public void img1click(View view) {
Bitmap image = BitmapFactory.decodeResource(getResources(), R.drawable.wodrob_1);
Product product = new Product(image);
Details details = new Details("Wodrob_1", "123", 123);
product.setDetails(details);
WodrobHandler.addObjectToWODROB(product);
Log.d(TAG, "img1click called");
canvas.updateCanvas();
}
}
activity_canvas.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.wodrob.wodrob_sylvester.CanvasActivity">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="#dimen/card_margin_horizontal"
android:background="#ffffff"
android:elevation="#dimen/canvas_elevation">
<com.example.wodrob.wodrob_sylvester.widget.WodrobView
android:id="#+id/canvas"
android:clickable="true"
android:layout_width="match_parent"
android:layout_height="250dp" />
</FrameLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="#dimen/card_margin_horizontal"
android:foreground="?attr/selectableItemBackground"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="150dp"
android:clickable="true"
android:scaleType="fitXY"
android:background="#color/black"
android:padding="1dp"
android:onClick="img1click"
android:src="#drawable/wodrob_1" />
<ImageView
android:layout_width="match_parent"
android:layout_height="150dp"
android:scaleType="fitXY"
android:background="#color/black"
android:padding="1dp"
android:src="#drawable/wodrob_2" />
<ImageView
android:layout_width="match_parent"
android:layout_height="150dp"
android:scaleType="fitXY"
android:background="#color/black"
android:padding="1dp"
android:src="#drawable/wodrob_3" />
<ImageView
android:layout_width="match_parent"
android:layout_height="150dp"
android:scaleType="fitXY"
android:background="#color/black"
android:padding="1dp"
android:src="#drawable/wodrob_4" />
</LinearLayout>
</ScrollView>
</LinearLayout>
Custom widget canvas (WodrobView.java)
public class WodrobView extends View {
private static final String TAG = WodrobView.class.getSimpleName();
private Context mContext;
public WodrobView(Context context) {
super(context);
mContext = context;
}
public WodrobView(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
mContext = context;
}
public WodrobView(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
}
#Override
public void draw(final Canvas canvas) {
super.draw(canvas);
Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
drawingImages(canvas);
}
});
}
private void drawingImages(Canvas canvas){
Map<Point, Product> drawMap = WodrobHandler.getObjects();
for (Point point : drawMap.keySet()){
Product product = drawMap.get(point);
if (product.isAdded()) {
Log.w(TAG, product.getDetails().getName() + " is already added!");
continue;
}
Bitmap bitmap = product.getBitmap();
Bitmap bitmapTemp = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth() / 2, bitmap.getHeight() / 2, false);
canvas.drawBitmap(bitmapTemp, point.x, point.y, new Paint(Paint.ANTI_ALIAS_FLAG));
}
}
public void updateCanvas() {
invalidate();
}
}
A WodrobHandler.java
public class WodrobHandler implements WodrobHelper {
interface WodrobHelper {
Point[] POINTS = new Point[]{
new Point(10, 10),
new Point(10, 10),
new Point(10, 10),
new Point(10, 10)
};
}
private static final String TAG = WodrobHandler.class.getSimpleName();
private static Map<Point, Product> objects = new HashMap<>();
private static short position = 0;
public static boolean addObjectToWODROB(Product product){
if (position >= 4 || position < 0){
Set<Point> pointSet = objects.keySet();
for (Point point:POINTS) {
short flag = 0;
for (Point point1:pointSet) {
if (point.equals(point1.x, point1.y))
flag++;
}
if (flag == 0) {
objects.put(point, product);
return true;
}
}
Log.e(TAG, "Invalid position or full");
return false;
} else {
objects.put(POINTS[position++], product);
return true;
}
}
public static boolean removeObjectFromWODROB(Product product){
if (!objects.containsValue(product)){
Log.e(TAG, "No such product to remove");
return false;
}
objects.remove(product.getPoint());
return true;
}
public static Map<Point, Product> getObjects() {
return objects;
}
public static void setObjects(Map<Point, Product> objects) {
WodrobHandler.objects = objects;
}
}
Product.java
public class Product {
private Bitmap bitmap;
private Details details;
Point point = null;
private boolean added = false;
public boolean isAdded() {
return added;
}
public void setAdded(boolean added) {
this.added = added;
}
public Product(Bitmap bitmap) {
//Getting bitmap from drawable resource
this.bitmap = bitmap;
}
public Bitmap getBitmap() {
return bitmap;
}
public Details getDetails() {
return details;
}
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}
public void setDetails(Details details) {
this.details = details;
}
}
Details.java
public class Details {
private String name, id;
private int cost;
public Details(String name, String id, int cost) {
this.name = name;
this.id = id;
this.cost = cost;
}
public String getName() {
return name;
}
public String getId() {
return id;
}
public int getCost() {
return cost;
}
}
I think objects in WodrobHandler is empty. Where are code you add element?
You have to convert bitmap to mutable and avoid create bitmap in onDraw. Create it on Construtor. Code create bitmap mutable:
Bitmap. createScaledBitmap(souce,souce.getWidth(),source.getHeight,false);
Related
I've searched, but haven't found anything I'm looking for, perhaps. I want load image into my custom drawing view. Here is the code of DrawingView that extend View.
private Path mDrawPath;
private Paint mBackgroundPaint;
private Paint mDrawPaint;
private Canvas mDrawCanvas;
private Bitmap mCanvasBitmap;
private ArrayList<Path> mPaths = new ArrayList<>();
private ArrayList<Paint> mPaints = new ArrayList<>();
private ArrayList<Path> mUndonePaths = new ArrayList<>();
private ArrayList<Paint> mUndonePaints = new ArrayList<>();
// Set default values
private int mBackgroundColor = 0xFFFFFFFF;
private int mPaintColor = 0xFF660000;
private int mStrokeWidth = 10;
public DrawingView(Context context, AttributeSet attrs)
{
super(context, attrs);
init();
}
private void init()
{
mDrawPath = new Path();
mBackgroundPaint = new Paint();
initPaint();
}
private void initPaint()
{
mDrawPaint = new Paint();
mDrawPaint.setColor(mPaintColor);
mDrawPaint.setAntiAlias(true);
mDrawPaint.setStrokeWidth(mStrokeWidth);
mDrawPaint.setStyle(Paint.Style.STROKE);
mDrawPaint.setStrokeJoin(Paint.Join.ROUND);
mDrawPaint.setStrokeCap(Paint.Cap.ROUND);
}
private void drawBackground(Canvas canvas)
{
mBackgroundPaint.setColor(Color.TRANSPARENT);
mBackgroundPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
mBackgroundPaint.setAntiAlias(true);
canvas.drawRect(0, 0, this.getWidth(), this.getHeight(), mBackgroundPaint);
}
private void drawPaths(Canvas canvas)
{
int i = 0;
for (Path p : mPaths)
{
canvas.drawPath(p, mPaints.get(i));
i++;
}
}
#Override
protected void onDraw(Canvas canvas)
{
drawBackground(canvas);
drawPaths(canvas);
canvas.drawPath(mDrawPath, mDrawPaint);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
mCanvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mDrawCanvas = new Canvas(mCanvasBitmap);
}
#Override
public boolean onTouchEvent(MotionEvent event)
{
float touchX = event.getX();
float touchY = event.getY();
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
mDrawPath.moveTo(touchX, touchY);
//mDrawPath.addCircle(touchX, touchY, mStrokeWidth/10, Path.Direction.CW);
break;
case MotionEvent.ACTION_MOVE:
mDrawPath.lineTo(touchX, touchY);
break;
case MotionEvent.ACTION_UP:
mDrawPath.lineTo(touchX, touchY);
mPaths.add(mDrawPath);
mPaints.add(mDrawPaint);
mDrawPath = new Path();
initPaint();
break;
default:
return false;
}
invalidate();
return true;
}
public void clearCanvas()
{
mPaths.clear();
mPaints.clear();
mUndonePaths.clear();
mUndonePaints.clear();
mDrawCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
invalidate();
}
public void setPaintColor(int color)
{
mPaintColor = color;
mDrawPaint.setColor(mPaintColor);
}
public void setPaintStrokeWidth(int strokeWidth)
{
mStrokeWidth = strokeWidth;
mDrawPaint.setStrokeWidth(mStrokeWidth);
}
public void setBackgroundColor(int color)
{
mBackgroundColor = color;
mBackgroundPaint.setColor(mBackgroundColor);
invalidate();
}
public Bitmap getBitmap()
{
drawBackground(mDrawCanvas);
drawPaths(mDrawCanvas);
return mCanvasBitmap;
}
public void undo()
{
if (mPaths.size() > 0)
{
mUndonePaths.add(mPaths.remove(mPaths.size() - 1));
mUndonePaints.add(mPaints.remove(mPaints.size() - 1));
invalidate();
}
}
public void redo()
{
if (mUndonePaths.size() > 0)
{
mPaths.add(mUndonePaths.remove(mUndonePaths.size() - 1));
mPaints.add(mUndonePaints.remove(mUndonePaints.size() - 1));
invalidate();
}
}
BoardActivity class code is:
private TextView titolo;
private DrawingView areaDisegno;
private ImageView sceltaColore, sceltaSpessore, undo, redo;
private Bitmap drawable;
private int mCurrentBackgroundColor;
private int mCurrentColor;
private int mCurrentStroke;
private static final int MAX_STROKE_WIDTH = 50;
#Override
protected void onCreate(Bundle savedInstanceState) {
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setNavigationBarColor(getResources().getColor(R.color.black));
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_board1);
titolo = findViewById(R.id.titolo);
titolo.setText("MATCHUP BOARD 1");
areaDisegno = findViewById(R.id.area_disegno);
sceltaColore= findViewById(R.id.scelta_colore);
sceltaSpessore = findViewById(R.id.scelta_spessore);
undo = findViewById(R.id.undo);
redo = findViewById(R.id.redo);
sceltaColore.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startColorPickerDialog();
}
});
sceltaSpessore.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startStrokeSelectorDialog();
}
});
undo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
areaDisegno.undo();
}
});
redo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
areaDisegno.redo();;
}
});
inizializzaAreaDisegno();
}
private void inizializzaAreaDisegno()
{
// mCurrentBackgroundColor = ContextCompat.getColor(this, android.R.color.white);
mCurrentColor = ContextCompat.getColor(this, android.R.color.black);
mCurrentStroke = 10;
areaDisegno.setBackgroundColor(mCurrentBackgroundColor);
areaDisegno.setPaintColor(mCurrentColor);
areaDisegno.setPaintStrokeWidth(mCurrentStroke);
}
private void startFillBackgroundDialog()
{
int[] colors = getResources().getIntArray(R.array.palette);
ColorPickerDialog dialog = ColorPickerDialog.newInstance(R.string.color_picker_default_title,
colors,
mCurrentBackgroundColor,
5,
ColorPickerDialog.SIZE_SMALL);
dialog.setOnColorSelectedListener(new ColorPickerSwatch.OnColorSelectedListener()
{
#Override
public void onColorSelected(int color)
{
mCurrentBackgroundColor = color;
areaDisegno.setBackgroundColor(mCurrentBackgroundColor);
}
});
dialog.show(getFragmentManager(), "ColorPickerDialog");
}
private void startColorPickerDialog()
{
int[] colors = getResources().getIntArray(R.array.palette);
ColorPickerDialog dialog = ColorPickerDialog.newInstance(R.string.color_picker_default_title,
colors,
mCurrentColor,
5,
ColorPickerDialog.SIZE_SMALL);
dialog.setOnColorSelectedListener(new ColorPickerSwatch.OnColorSelectedListener()
{
#Override
public void onColorSelected(int color)
{
mCurrentColor = color;
areaDisegno.setPaintColor(mCurrentColor);
}
});
dialog.show(getFragmentManager(), "ColorPickerDialog");
}
private void startStrokeSelectorDialog()
{
StrokeSelectorDialog dialog = StrokeSelectorDialog.newInstance(mCurrentStroke, MAX_STROKE_WIDTH);
dialog.setOnStrokeSelectedListener(new StrokeSelectorDialog.OnStrokeSelectedListener()
{
#Override
public void onStrokeSelected(int stroke)
{
mCurrentStroke = stroke;
areaDisegno.setPaintStrokeWidth(mCurrentStroke);
}
});
dialog.show(getSupportFragmentManager(), "StrokeSelectorDialog");
}
private void startShareDialog(Uri uri)
{
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setType("image/*");
intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "");
intent.putExtra(android.content.Intent.EXTRA_TEXT, "");
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(intent, "Share Image"));
}
private void requestPermissionsAndSaveBitmap()
{
if (PermissionManager.checkWriteStoragePermissions(this))
{
Uri uri = FileManager.saveBitmap(this, areaDisegno.getBitmap());
startShareDialog(uri);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
{
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
{
case PermissionManager.REQUEST_WRITE_STORAGE:
{
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
Uri uri = FileManager.saveBitmap(this, areaDisegno.getBitmap());
startShareDialog(uri);
} else
{
Toast.makeText(this, "The app was not allowed to write to your storage. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show();
}
}
}
}
And Layout used is:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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"
android:background="#drawable/sfondo"
tools:context=".activities.Board1">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar_menu_disegno"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/toolbar"
android:orientation="vertical"
android:weightSum="2"
>
<FrameLayout
android:layout_weight="1.99"
android:layout_width="match_parent"
android:layout_height="0dp" >
<it.colan.matchup.ui.component.DrawingView
android:id="#+id/area_disegno"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:rotation="90"
android:src="#drawable/board_1" />
</FrameLayout>
<LinearLayout
android:id="#+id/menu_strumenti"
android:layout_weight="0.01"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/area_disegno"
android:orientation="horizontal"
android:gravity="center"
android:background="#color/black">
<ImageView
android:id="#+id/scelta_colore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_palette"
android:padding="15dp"
android:clickable="true"
android:background="?attr/selectableItemBackgroundBorderless"/>
<ImageView
android:id="#+id/scelta_spessore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_peso_linea"
android:padding="15dp"
android:clickable="true"
android:background="?attr/selectableItemBackgroundBorderless"/>
<ImageView
android:id="#+id/undo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_undo"
android:padding="15dp"
android:clickable="true"
android:background="?attr/selectableItemBackgroundBorderless"/>
<ImageView
android:id="#+id/redo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_redo"
android:padding="15dp"
android:clickable="true"
android:background="?attr/selectableItemBackgroundBorderless"/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
I have two problems:
The drawing does it for me behind the image and not above
imagebug
The background of the image is not full screen with margins.
How should I do?
Thanks
Cris
I have a ListView, inside a linear layout, that should show items based on a list_item.xml layout file. In the layout file I have two ImageViews and two TextViews. I'm using my custom ArrayAdapter to fill the ListView at runtime with Bitmap images of scale 125x25, however images are showing smaller than their initial size when rendered by the ImageView inside the ListView as shown in the screenshot (of a single list item) below:
ActivityLayout.xml:
...
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:paddingTop="40dp"
android:orientation="vertical">
<ListView
android:id="#+id/lvExp"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
...
List_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="?android:attr/listPreferredItemHeight">
<ImageView
android:id="#+id/imageViewplate"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:adjustViewBounds="true"
android:minWidth="300dp" />
<TextView
android:id="#+id/lblListItem_letter"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_toRightOf="#id/imageViewplate"
android:padding="3dp"
android:text="A"
android:textSize="17dip" />
<TextView
android:id="#+id/lblListItem_num"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_toRightOf="#id/lblListItem_letter"
android:padding="3dp"
android:text="123456"
android:textSize="17dip" />
<ImageView
android:id="#+id/imageViewchars"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginLeft="10dp"
android:paddingTop="3dp"
android:paddingBottom="3dp" />
</RelativeLayout>
My custom list adapter:
package bi.anpr.layouts;
import android.content.Context;
import android.support.design.widget.Snackbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.sxx.vlctest.R;
import java.util.ArrayList;
import bi.anpr.agents.Plate;
public class PlateListAdapter extends ArrayAdapter<Plate>{
public PlateListAdapter(Context context, int resource) {
super(context, resource);
}
private ArrayList<Plate> dataSet;
Context mContext;
private static class ViewHolder {
public ImageView imageView_plate, imageView_chars;
public TextView textView_letter, textView_numbers;
}
private int lastPosition = -1;
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Plate plate = getItem(position);
ViewHolder viewHolder;
final View result;
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.list_item, parent, false);
viewHolder.textView_letter = (TextView) convertView.findViewById(R.id.lblListItem_letter);
viewHolder.textView_numbers = (TextView) convertView.findViewById(R.id.lblListItem_num);
viewHolder.imageView_plate = (ImageView) convertView.findViewById(R.id.imageViewplate);
viewHolder.imageView_chars = (ImageView) convertView.findViewById(R.id.imageViewchars);
result = convertView;
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
result = convertView;
}
lastPosition = position;
try{
viewHolder.imageView_plate.setImageBitmap(plate.getEngPartImageIcon());
viewHolder.imageView_chars.setImageBitmap(plate.getcharsImageIcon());
viewHolder.textView_letter.setText(Character.toString(plate.getPlateLetter()));
viewHolder.textView_numbers.setText(plate.getPlateNumbersAsString());
}catch (Exception e){
e.printStackTrace();
}
// Return the completed view to render on screen
return convertView;
}
}
Plate.java:
package bi.anpr.agents;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import java.io.Serializable;
import java.util.ArrayList;
import org.opencv.core.Mat;
import org.opencv.core.Rect;
import bi.anpr.core.IPHelper;
public class Plate implements Serializable {
private String platePath;
private boolean isWidePlate = true;
private int[] color;
private String colorString;
private String source = "";
private Rect bdgbx;
private Mat srcImage;
private Mat plateImage;
private Bitmap engPartImageIcon, plateImageIcon, forCutImageIcon, charsImageIcon, charsTextImageIcon;
private Mat engPartImage;
private Mat forCut;
private ArrayList<Character> plateNumberChars = new ArrayList<>();
private char plateLetterChar = '#';
private String fullPlateString = "";
private String numbersPlateString = "";
private double letterRate = 0;
private double numbersRate = 0;
private double accuracy = 0;
private int id;
private PlateRecogInfo plateRecogInfo;
private ArrayList<Bitmap> charsIcons = new ArrayList<>();
private boolean ignore = false;
private int accurayPercent = 0;
public Plate() {
plateRecogInfo = new PlateRecogInfo();
}
public void addPlateNumberChar(char c) {
plateNumberChars.add(c);
}
public Bitmap getplateImageIcon() {
return plateImageIcon;
}
public void setPlateImageIcon(Bitmap plateImageIcon) {
this.plateImageIcon = plateImageIcon;
}
public Bitmap getEngPartImageIcon() {
if (engPartImageIcon == null) {
engPartImageIcon = IPHelper.matToBitmap(engPartImage);
}
return engPartImageIcon;
}
public void setEngPartImageIcon(Bitmap engPartImageIcon) {
this.engPartImageIcon = engPartImageIcon;
}
public Mat getEngPartImage() {
return engPartImage;
}
public void setEngPartImage(Mat engPartImage) {
this.engPartImage = engPartImage;
}
public boolean isWidePlate() {
return isWidePlate;
}
public void setWidePlate(boolean isWidePlate) {
this.isWidePlate = isWidePlate;
}
public Mat getImage() {
return plateImage;
}
public void setImage(Mat Bitmap) {
plateImage = Bitmap;
}
public Bitmap getForCutImageIcon() {
if (forCutImageIcon == null) {
forCutImageIcon = IPHelper.matToBitmap(forCut);
}
return forCutImageIcon;
}
public Mat getForCut() {
return forCut;
}
public void setForCutImageIcon(Bitmap forCutImageIcon) {
this.forCutImageIcon = forCutImageIcon;
}
public void setForCut(Mat forCut) {
this.forCut = forCut;
}
public ArrayList<Character> getPlateNumberChar() {
return plateNumberChars;
}
public void setPlateNumberChar(ArrayList<Character> nchar) {
plateNumberChars = new ArrayList<Character>(nchar);
}
public char getPlateLetter() {
return plateLetterChar;
}
public void setPlateLetter(char plateLetter) {
plateLetterChar = plateLetter;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getLetterRate() {
return letterRate;
}
public void setLetterRate(double letterRate) {
this.letterRate = letterRate;
}
public double getCharsRate() {
return numbersRate;
}
public void setNumbersRate(double NumbersRate) {
this.numbersRate = NumbersRate;
}
public double getAccuracy() {
return accuracy;
}
public int getAccurayPercent() {
return accurayPercent;
}
public void setAccuracy(double totalRate) {
this.accuracy = totalRate;
this.accurayPercent = (int) (totalRate * 100);
}
public Mat getPlateImage() {
return plateImage;
}
public void setPlateImage(Mat matImage) {
this.plateImage = matImage;
plateImageIcon = IPHelper.matToBitmap(matImage);
}
public PlateRecogInfo getPlateRecogInfo() {
return plateRecogInfo;
}
public void setPlateRecogInfo(PlateRecogInfo plateRecogInfo) {
this.plateRecogInfo = plateRecogInfo;
}
public void addCharIcon(Mat charsIcons) {
this.charsIcons.add(IPHelper.matToBitmap(charsIcons));
}
public Bitmap getcharsImageIcon() {
if (charsImageIcon == null) {
int width = 5;
int height = 0;
for (Bitmap icon : charsIcons) {
if (icon.getHeight() > height)
height = icon.getHeight();
width += icon.getWidth() + 5;
}
height += 6;
charsImageIcon = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(charsImageIcon);
int i = 0;
for (Bitmap icon : charsIcons) {
canvas.drawBitmap(icon, i, 3, null);
i += icon.getWidth() + 5;
}
}
return charsImageIcon;
}
public Bitmap getCharsTextImageIcon() {
if (charsTextImageIcon == null) {
String chars = "";
for (Character c : plateNumberChars) {
String cs = c.toString();
chars += cs;
}
int width = 5;
int height = 0;
for (Bitmap icon : charsIcons) {
if (icon.getHeight() > height)
height = icon.getHeight();
width += icon.getWidth() + 5;
}
height += 6;
charsTextImageIcon = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(charsTextImageIcon);
int i = 0;
int j = 0;
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
paint.setColor(Color.BLACK);
paint.setTextSize(16);
canvas.drawColor(Color.WHITE);
for (Bitmap icon : charsIcons) {
if (j == 0)
canvas.drawText("Some Text", i + 2, 19, paint);
else
canvas.drawText(Character.toString(chars.charAt(j - 1)), i + 3, 19, paint);
i += icon.getWidth() + 5;
j++;
}
}
return charsTextImageIcon;
}
public void setCharsTextImageIcon(Bitmap charsTextImageIcon) {
this.charsTextImageIcon = charsTextImageIcon;
}
public Mat getSrcImage() {
return srcImage;
}
public void setSrcImage(Mat srcImage) {
this.srcImage = srcImage;
}
public Rect getBdgbx() {
return bdgbx;
}
public void setBdgbx(Rect bdgbx) {
this.bdgbx = bdgbx;
}
public int[] getColor() {
return color;
}
// public Color getColorObject() {
// int[] color = getColor();
//
// try {
// return Color.parseColor(Color.rgb(color[0], color[1], color[2]));
// } catch (Exception e) {
// }
// return null;
// }
public void setColor(int[] is) {
this.color = is;
}
public String getColorString() {
return colorString;
}
public void setColorString(String colorString) {
this.colorString = colorString;
}
public String getFullPlateCharsString() {
if (fullPlateString == "" || fullPlateString == null) {
fullPlateString += plateLetterChar;
for (Character c : plateNumberChars) {
fullPlateString += c.toString();
}
}
return fullPlateString;
}
public void setFullPlateString(String fullPlateString) {
this.fullPlateString = fullPlateString;
}
public void setNumbersPlateString(String numbersPslateString) {
this.numbersPlateString = numbersPslateString;
}
public String getPlateNumbersAsString() {
if (numbersPlateString == "" || numbersPlateString == null) {
for (Character c : plateNumberChars) {
numbersPlateString += c.toString();
}
}
return numbersPlateString;
}
public String getPlatePath() {
return platePath;
}
public void setPlatePath(String platePath) {
this.platePath = platePath;
}
public boolean isIgnore() {
return ignore;
}
public void setIgnore(boolean ignore) {
this.ignore = ignore;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
}
Usage:
PlateListAdapter plateListAdapter = new PlateListAdapter(getApplicationContext(), R.layout.list_item);
ListView resultsListView = (ListView) findViewById(R.id.lvExp);
resultsListView.setAdapter(plateListAdapter);
plateListAdapter.addAll(recogInfo.getPlates());
plateListAdapter.notifyDataSetChanged();
Using definite dimensions for ImageView's, rather than wrap_content solved the problem.
I have the Android app page (on fragment) with MvxGridView with such layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<MvxGridView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:numColumns="1"
android:horizontalSpacing="0dp"
android:verticalSpacing="0dp"
local:MvxBind="ItemsSource DayGraphsItems"
local:MvxItemTemplate="#layout/day_graph_item" />
</LinearLayout>
I have a custom view for drawing graph:
public class GraphView : View
{
Paint mPaint;
Bitmap mBitmap;
Canvas mCanvas;
Path mPath;
Paint mBitmapPaint;
public List<string> Data { get; set; }
public GraphView(Context context, Android.Util.IAttributeSet attributeSet) : base(context)
{
mPaint = new Paint();
mPaint.AntiAlias = true;
mPaint.Dither = true;
mPaint.SetARGB(0xFF, 0xFF, 0xFF, 0xFF);
mPaint.SetStyle(Paint.Style.FillAndStroke);
mPaint.StrokeJoin = Paint.Join.Round;
mPaint.StrokeCap = Paint.Cap.Round;
mPaint.StrokeWidth = 1;
mPaint.TextSize = 24;
mPath = new Path();
mBitmapPaint = new Paint();
mBitmapPaint.SetARGB(0xFF, 0xFF, 0xff, 0xff);
}
protected override void OnSizeChanged(int w, int h, int oldw, int oldh)
{
if (w > 0 && h > 0)
{
mBitmap = Bitmap.CreateBitmap(w, h, Bitmap.Config.Argb8888);
mCanvas = new Canvas(mBitmap);
_canvasHeight = h;
_canvasWidth = w;
DrawTheGraph(Data);
}
}
public override void Draw(Canvas canvas)
{
canvas.DrawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.DrawPath(mPath, mPaint);
canvas.Restore();
}
private void DrawTheGraph(List<string> data)
{
// here is drawing of the graph which works well
}
}
I have the custom binding
public class GraphCustomBinding : MvxConvertingTargetBinding
{
public static string Name = "GraphCustom";
public GraphCustomBinding(GraphView target) : base(target)
{
}
protected override void SetValueImpl(object target, object value)
{
var data = new List<string>();
data = (List<string>)value;
var targetGraphView = (GraphView)target;
targetGraphView.Data = data;
}
public override Type TargetType
{
get { return typeof(GraphView); }
}
}
Binding is correctly registered in setup.
I have item's layout for the elements of DayGraphsItems list
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingTop="15dp"
android:paddingBottom="15dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
style="#style/TextViewCurrentConditionsHeader"
local:MvxBind="Text Title" />
<Pogoda.Droid.GraphView
android:layout_width="match_parent"
android:layout_height="300dp"
android:padding="5dp"
local:MvxBind="GraphCustom Data, Mode=TwoWay" />
</LinearLayout>
EDIT:
DayGraphsItems is a list of DayGraphItem which is given as follows:
public class DayGraphItem
{
public int Id { get; set; }
public string Title { get; set; }
public List<string> Data { get; set; }
}
View is on fragment:
[Register("pogoda.droid.DayGraphsFragment")]
public class DayGraphsFragment : BaseFragment<DayGraphsViewModel>
{
public const string TAG = "DayGraphsFragmentTag";
public override string UniqueImmutableCacheTag
{
get
{
return TAG;
}
}
public override Android.Views.View OnCreateView(Android.Views.LayoutInflater inflater, Android.Views.ViewGroup container, Android.OS.Bundle savedInstanceState)
{
base.OnCreateView(inflater, container, savedInstanceState);
return this.BindingInflate(Resource.Layout.day_graphs_layout, null);
}
}
Problem: The graphs are drawn correctly, but in the case when there are more cells than could be displayed at once on the screen, after I scroll down I see the cells which was drawn before instead of new ones (seem to be reused).
QUESTION: How to avoid this and display fresh graphs instead of these "scrolled out from the top"?
Solution which works for me is
Create EnhancedMvxListView and replace MvxGridView using it in point 1.
public class EnhancedMvxListView : MvxListView
{
public EnhancedMvxListView(Context context, IAttributeSet attrs) : base(context, attrs, new EnhancedMvxAdapter(context))
{
}
public EnhancedMvxListView(Context context, IAttributeSet attrs, IMvxAdapter adapter) : base(context, attrs, new EnhancedMvxAdapter(context))
{
}
}
where EnhancedMvxAdapter is the following
public class EnhancedMvxAdapter : MvxAdapterWithChangedEvent
{
public EnhancedMvxAdapter(Context context) : base(context)
{
}
protected override View GetBindableView(View convertView, object dataContext, ViewGroup parent, int templateId)
{
templateId = GetTemplateId(dataContext);
var view = base.GetBindableView(convertView, dataContext, parent, templateId);
var context = dataContext as DayGraphItem;
view.FindViewById<TextView>(Resource.Id.graphTitle).Text = context.Title;
view.FindViewById<GraphView>(Resource.Id.graphDrawing).Data = context.Data;
return view;
}
private int GetTemplateId(object data)
{
return Resource.Layout.day_graph_item;
}
}
And finally in file in point 2. I've replaced
public List<string> Data { get; set; }
with
List<string> _data;
public List<string> Data
{
get
{
return _data;
}
set
{
if (value != null && value != _data)
{
_data = value;
if ((int)_canvasWidth == 0 || (int)_canvasHeight == 0)
return;
mBitmap = Bitmap.CreateBitmap((int)_canvasWidth, (int)_canvasHeight, Bitmap.Config.Argb8888);
mCanvas = new Canvas(mBitmap);
DrawTheGraph(Data);
}
}
}
I have a trapezoid shape created in custom view using below code.
#Override
protected void onDraw(Canvas canvas) {
trapezoidPath.moveTo(0,0);
trapezoidPath.lineTo(getWidth() ,0);
trapezoidPath.lineTo(getWidth() , altitude);
trapezoidPath.lineTo(0,getHeight());
trapezoidPath.lineTo(0,0);
trapezoidPath.close();
canvas.drawPath(trapezoidPath,paintTrapezoid);
}
The drawn shape looks like this.
I want to move (0,height) point to top until trapezoid shape become a rectangle. After that I want to move bottom line up until shape become a line.
Is there any way to access created path lines and it's point and manipulate them to achieve what I want ? If not how can I achieve this ?
I have to animate this shape base on user response. Thank you.
Use an ObjectAnimator to change the variables you use in onDraw. Below is an example of how you could implement this.
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TrapezoidView trapezoidView = findViewById(R.id.trapezoid);
final Button resetButton = findViewById(R.id.btn_reset);
resetButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
trapezoidView.reset();
}
});
final Button animateButton = findViewById(R.id.btn_animate);
animateButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
animateButton.setEnabled(false);
resetButton.setEnabled(false);
trapezoidView.toNewState();
}
});
trapezoidView.setListener(new TrapezoidView.TrapezoidListener() {
#Override
public void onNewState() {
animateButton.setEnabled(true);
resetButton.setEnabled(true);
}
});
}
}
TrapezoidView.java
public class TrapezoidView extends View {
public interface TrapezoidListener {
void onNewState();
}
public static final int TRAPEZOID_STATE = 0;
public static final int RECTANGLE_STATE = 1;
public static final int LINE_STATE = 2;
private int mState = TRAPEZOID_STATE;
private Paint mTrapezoidPaint;
private Path mTrapezoidPath = new Path();
private int mAnimationDuration = 5000; // 5 s in millis
private float mRectangleHeight = dpTopx(200);
private float mAltitude = mRectangleHeight;
private TrapezoidListener mListener;
public TrapezoidView(Context context, AttributeSet attrs) {
super(context, attrs);
mTrapezoidPaint = new Paint();
mTrapezoidPaint.setColor(Color.BLACK);
mTrapezoidPaint.setStrokeWidth(5.0f);
mTrapezoidPaint.setStyle(Paint.Style.STROKE);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mTrapezoidPath.reset();
if (mState == TRAPEZOID_STATE) {
mAltitude = getHeight();
}
mTrapezoidPath.moveTo(0, 0);
mTrapezoidPath.lineTo(getWidth(), 0);
if (mState == LINE_STATE) {
mTrapezoidPath.lineTo(getWidth(), mAltitude);
mTrapezoidPath.lineTo(0, mAltitude);
} else {
mTrapezoidPath.lineTo(getWidth(), mRectangleHeight);
mTrapezoidPath.lineTo(0, mAltitude);
}
mTrapezoidPath.lineTo(0, 0);
mTrapezoidPath.close();
canvas.drawPath(mTrapezoidPath, mTrapezoidPaint);
}
private float dpTopx(int dp) {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
}
public float getAltitude() {
return mAltitude;
}
public void setAltitude(float altitude) {
this.mAltitude = altitude;
invalidate();
}
public void reset() {
mState = TRAPEZOID_STATE;
mRectangleHeight = dpTopx(200);
mAltitude = mRectangleHeight;
invalidate();
}
public void setListener(TrapezoidListener listener) {
mListener = listener;
}
public void toNewState() {
if (mState == LINE_STATE) {
mListener.onNewState();
return;
}
float start;
float target;
final int targetState = mState == TRAPEZOID_STATE ? RECTANGLE_STATE : LINE_STATE;
if (targetState == RECTANGLE_STATE) {
start = getHeight();
target = mRectangleHeight;
} else {
start = mAltitude;
target = 0.0f;
}
ObjectAnimator stateAnimation = ObjectAnimator.ofFloat(TrapezoidView.this, "Altitude", start);
stateAnimation.setFloatValues(target);
stateAnimation.setDuration(mAnimationDuration);
stateAnimation.addListener(
new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
mState = targetState;
}
#Override
public void onAnimationEnd(Animator animation) {
mListener.onNewState();
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
}
);
stateAnimation.start();
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="50dp"
tools:context="test.example.MainActivity">
<test.example.TrapezoidView
android:id="#+id/trapezoid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.9" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.1"
android:orientation="horizontal">
<Button
android:id="#+id/btn_animate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Animate!" />
<Button
android:id="#+id/btn_reset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Reset" />
</LinearLayout>
</LinearLayout>
I have a fullscreen activity that should look like this:
where the big white circle would have some text, I've already done it, but the problem is that I don't know how to do that dashed lines between the icons, also they want a little animation in the icons, so I assumed that each one should be a separate view, so far I've done this (it doesn't need to look exactly the same):
So, how could I draw that lines? Also if I could make that dashes to "run" acrross the lines would be awesome.
this is my xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/rlt_welcome"
android:layout_weight="9"
android:background="#drawable/bg"
>
<RelativeLayout
android:layout_width="0dp"
android:layout_weight="2"
android:orientation="vertical"
android:padding="10dp"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:id="#+id/img_youtube"
android:src="#drawable/youtube_circle"
android:layout_marginTop="60dp"
android:layout_marginRight="60dp"
android:layout_height="wrap_content"
/>
<ImageView
android:layout_width="wrap_content"
android:src="#drawable/tablet_circle"
android:layout_height="wrap_content"
android:layout_above="#+id/img_stats"
android:layout_marginRight="30dp"
android:layout_below="#+id/img_youtube"
/>
<ImageView
android:layout_width="wrap_content"
android:id="#+id/img_stats"
android:src="#drawable/stats_circle"
android:layout_height="wrap_content"
android:layout_marginRight="70dp"
android:layout_marginBottom="20dp"
android:layout_alignParentBottom="true"/>
<ImageView
android:id="#+id/img_iphone"
android:layout_width="wrap_content"
android:src="#drawable/iphone_circle"
android:layout_height="wrap_content"
android:layout_marginLeft="60dp"
/>
<ImageView
android:layout_width="wrap_content"
android:src="#drawable/imac_circle"
android:layout_height="wrap_content"
android:layout_below="#+id/img_iphone"
android:layout_marginLeft="70dp"
android:layout_marginTop="-30dp"
/>
<ImageView
android:layout_width="wrap_content"
android:src="#drawable/webcam_circle"
android:layout_height="wrap_content"
android:layout_marginLeft="60dp"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_weight="5"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center_vertical"
android:padding="40dp"
android:textSize="25sp"
android:textColor="#color/text1"
android:layout_margin="20dp"
android:text="Bienvenido"
android:background="#drawable/flat_circle"
android:id="#+id/txt_welcome"
android:layout_centerInParent="true" />
</RelativeLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="match_parent"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/arrow_circle"
android:id="#+id/img_arrow"
android:layout_alignParentTop="true"
android:layout_marginRight="60dp"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/news_circle"
android:layout_below="#+id/img_arrow"
android:layout_marginTop="-90dp"
android:layout_marginRight="2dp"
android:layout_marginLeft="70dp"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/line_circle"
android:id="#+id/img_line"
android:layout_below="#+id/img_arrow"
android:layout_marginTop="-10dp"
android:layout_marginRight="70dp"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/money_circle"
android:layout_below="#+id/img_line"
android:layout_marginRight="6dp"
android:layout_marginTop="-70dp"
android:layout_marginLeft="70dp"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/mouse_circle"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginRight="80dp"
/>
</RelativeLayout>
</LinearLayout>
Please check this, may be this will help you
http://www.rengelbert.com/tutorial.php?id=182
How do I get this work, I made a new activity that holds a Canvas controller, and place the bitmaps on the canvas and draw the lines between them with this, I didn't use any external library:
Hope someone could reuse some code and not only been told to google it.
MainActivty.java
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
relativeMainActivity = (RelativeLayout) findViewById(R.id.rlt_main);
DisplayMetrics dm = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(dm);
final int heightS = dm.heightPixels;
final int widthS = dm.widthPixels;
Log.d("MainActvitiy", "widht:" + widthS);
myPanel = new Panel(getApplicationContext(),this,widthS, heightS);
relativeMainActivity.addView(myPanel);
RelativeLayout RR = new RelativeLayout(this);
RR.setGravity(Gravity.CENTER);
relativeMainActivity.addView(RR,400,150);
RR.setX(0);
LayoutInflater myInflater = (LayoutInflater) getApplicationContext().getSystemService(getApplicationContext().LAYOUT_INFLATER_SERVICE);
}
Panel.java
public class Panel extends SurfaceView implements SurfaceHolder.Callback {
public MainThread thread;
private Background background;
private CircleManager CM;
public int ScreenWidth;
public int Screenheigt;
private CircleIcon icon1;
private CircleIcon icon2;
private CircleIcon icon3;
//and so on
public MainActivity myMain;
public Panel(Context context, MainActivity _main, int width , int height) {
super(context);
getHolder().addCallback(this);
this.myMain = _main;
this.ScreenWidth=width;
this.Screenheigt=height;
thread = new MainThread(getHolder(),this);
background = new Background(BitmapFactory.decodeResource(getResources(), R.drawable.bg), Screenheigt, this);
CM = new CircleManager( this,context,ScreenWidth);
CM.setScreen(ScreenWidth, Screenheigt);
SetIcons();
CM.setManager();
setFocusable(true);
}
void SetIcons()
{
icon1 = new CircleIcon(BitmapFactory.decodeResource(getResources(),R.drawable.circle_iphone),39,40);
icon2 = new CircleIcon(BitmapFactory.decodeResource(getResources(),R.drawable.circle_chat),280,40);
icon3 = new CircleIcon(BitmapFactory.decodeResource(getResources(),R.drawable.circle_youtube),60,200);
//and so on
icon1.myConnections.add(2);
icon1.myConnections.add(3);
icon2.myConnections.add(15);
icon3.myConnections.add(4);
icon3.myConnections.add(5);
//and so on
CM.iconsList.add(icon1);
CM.iconsList.add(icon2);
CM.iconsList.add(icon3);
//and so on
}
void Draw(Canvas canvas){
if (canvas!=null)
{
background.draw(canvas);
CM.draw(canvas);
iconEvent.draw(canvas);
}
}
void Update(float dt)
{
CM.Update(dt);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
thread.setRunning(true);
thread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
boolean retry = true;
while (retry)
{
try
{
thread.join();
retry=false;
}
catch (InterruptedException e)
{
}
}
}
}
Background.java
public class Background {
Bitmap BackBitmap;
int x,y;
int ScreenHeight;
Panel root_panel;
public Background(Bitmap bitmap , int Screen_h, Panel _panel) {
this.BackBitmap = bitmap;
this.x=0;
this.y=0;
this.ScreenHeight=Screen_h;
root_panel =_panel;
}
public void draw(Canvas canvas)
{
canvas.drawBitmap(BackBitmap,x,y, null);
}
}
CircleIcon.java
public class CircleIcon {
private Bitmap bitmap;
private int x;
private int y;
CircleManager circManager;
ArrayList<Integer> myConnections;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y=y;
}
public CircleIcon(Bitmap icon, int x, int y) {
bitmap=icon;
this.x=x;
this.y=y;
myConnections = new ArrayList<>();
}
public ArrayList<Integer> getMyConnections() {
return myConnections;
}
public void setMyConnections(ArrayList<Integer> myConnections) {
this.myConnections = myConnections;
}
public void setManager(CircleManager icManager) {
circManager = icManager;
}
public Bitmap getBitmap()
{
return bitmap;
}
public void setBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
}
public void draw(Canvas canvas) {
canvas.drawBitmap(bitmap, x, y, null);
}
public void update()
{
// x=+1; example
}
}
CircleManager.java
public class CircleManager {
Bitmap icons;
int screenWidth;
int hour;
int min;
Context myContext;
int ScreenWidht;
public Panel myPanel;
public ArrayList<CircleIcon> iconsList;
public CircleManager(Panel _Panel, Context context,int screenW) {
this.myPanel = _Panel;
this.screenWidth = screenW;
this.myContext = context;
iconsList = new ArrayList<CircleIcon>();
}
public void setScreen(int screenWidth, int screenHeight)
{
this.ScreenWidht=screenWidth;
}
public void draw(Canvas canvas)
{
drawLines(canvas);
for(CircleIcon myIcon: iconsList)
{
myIcon.draw(canvas);
}
}
public void Update(float dt)
{
//some animation updates
}
public void drawLines(Canvas canvas)
{
Paint mPaint = new Paint();
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(2);
mPaint.setPathEffect(new DashPathEffect(new float[]{7, 5}, 0));
for (CircleIcon myIcon: iconsList)
{
for( int connectedIcon: myIcon.getMyConnections())
{
Path mPath;
mPath = new Path();
mPath.moveTo(myIcon.getX()+myIcon.getBitmap().getWidth()/2, myIcon.getY()+myIcon.getBitmap().getHeight()/2);
mPath.lineTo(iconsList.get(connectedIcon-1).getX()+myIcon.getBitmap().getWidth()/2, iconsList.get(connectedIcon-1).getY()+myIcon.getBitmap().getHeight()/2);
canvas.drawPath(mPath, mPaint);
}
}
}
public void setManager()
{
for(CircleIcon myIcon: iconsList)
{
myIcon.setManager(this);
}
}
}