How to draw triangle shape and add it into relative or linear layout android

nilkash picture nilkash · Mar 1, 2013 · Viewed 12.2k times · Source

I am developing small android application in which I m using my custom linear layout class. In that class i tried to draw one small triangle and tried to include it in to my linear layout but I m not able to do that. I tried it in following ways ...

@SuppressLint("DrawAllocation")
public class SimpleLin extends LinearLayout {
    public String TAG = "CustomviewActivity";   
    LinearLayout parentLayout;

    public SimpleLin(Context context) 
    {
        super(context);
        LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if(inflater != null){   
        view = inflater.inflate(R.layout.main2, this);d.lin_llt);
        parentLayout.setBackgroundResource(R.drawable.bcd);

      }

    }

    public SimpleLin(Context context, AttributeSet attrs) {

        super( context, attrs );

        context1= context;
    }

    protected void onDraw(Canvas canvas) {

        super.onDraw(canvas);
        Log.i("############################", "inside ondraw");
        Paint p = new Paint();
        p.setStyle(Style.FILL);
        p.setColor(Color.RED);
        Point point = new Point();
        point.x = 80;
        point.y = 80;
        Path path = getEquilateralTriangle(point, 70, Direction.SOUTH);
        Bitmap b = Bitmap.createBitmap(500, 500, Bitmap.Config.ARGB_8888);
        canvas.drawPath(path, p);
    }
    public static Path getEquilateralTriangle(Point p1, int width, Direction direction) {
        Point p2 = null, p3 = null;

        if (direction == Direction.NORTH) {
            p2 = new Point(p1.x + width, p1.y);
            p3 = new Point(p1.x + (width / 2), p1.y - width);
        }
        else if (direction == Direction.SOUTH) {
            p2 = new Point(p1.x + width,p1.y);
            p3 = new Point(p1.x + (width / 2), p1.y + width);
        }
        else if (direction == Direction.EAST) {
            p2 = new Point(p1.x, p1.y + width);
            p3 = new Point(p1.x - width, p1.y + (width / 2));
        }
        else if (direction == Direction.WEST) {
            p2 = new Point(p1.x, p1.y + width);
            p3 = new Point(p1.x + width, p1.y + (width / 2));
        }

        Path path = new Path();
        path.moveTo(p1.x, p1.y);
        path.lineTo(p2.x, p2.y);
        path.lineTo(p3.x, p3.y);

        return path;
    }
    public enum Direction 
    {
        NORTH, SOUTH, EAST, WEST;
    }

    @SuppressWarnings("deprecation")
    public void initialiseImages()
    {
        invalidate();
    }
}

I am calling initialiseImages method from my activity where i wanted to use this custom layout. So problem is that It not calling my on draw method when i use invalidate(). That's why it not drawing my triangle. and I am also confuse how to include that triangle into my parentlayout.. Is there wrong in my code.. How to draw such shapes in android... Need help... Thank you...

Answer

Abhishek Nandi picture Abhishek Nandi · Mar 1, 2013

Code for Custom Linear Layout (I modified your code so its easier for you to understand)

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.Point;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.LinearLayout;

/**
 * @author Atrix1987
 * 
 */
public class CustomView extends LinearLayout {

    /**
     * @param context
     */
    public CustomView(Context context) {
        super(context);
        commonConstructor(context);
    }

    /**
     * @param context
     * @param attrs
     */
    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        commonConstructor(context);
    }

    /**
     * 
     */
    Paint trianglePaint;
    /**
     * 
     */
    Path trianglePath;

    /**
     * @param context
     */
    private void commonConstructor(Context context) {
        trianglePaint = new Paint();
        trianglePaint.setStyle(Style.FILL);
        trianglePaint.setColor(Color.RED);
        Point point = new Point();
        point.x = 80;
        point.y = 80;
        trianglePath = getEquilateralTriangle(point, 70, Direction.SOUTH);
    }

    @Override
    protected void onDraw(Canvas canvas) {

        Log.i("Sample", "inside ondraw");
        //avoid creating objects in onDraw
        canvas.drawPath(trianglePath, trianglePaint);
    }

    private Path getEquilateralTriangle(Point p1, int width, Direction direction) {
        Log.i("Sample", "inside getEqui");
        Point p2 = null, p3 = null;

        if (direction == Direction.NORTH) {
            p2 = new Point(p1.x + width, p1.y);
            p3 = new Point(p1.x + (width / 2), p1.y - width);
        } else if (direction == Direction.SOUTH) {
            p2 = new Point(p1.x + width, p1.y);
            p3 = new Point(p1.x + (width / 2), p1.y + width);
        } else if (direction == Direction.EAST) {
            p2 = new Point(p1.x, p1.y + width);
            p3 = new Point(p1.x - width, p1.y + (width / 2));
        } else if (direction == Direction.WEST) {
            p2 = new Point(p1.x, p1.y + width);
            p3 = new Point(p1.x + width, p1.y + (width / 2));
        }

        Path path = new Path();
        path.moveTo(p1.x, p1.y);
        path.lineTo(p2.x, p2.y);
        path.lineTo(p3.x, p3.y);

        return path;
    }

    public enum Direction {
        NORTH, SOUTH, EAST, WEST;
    }

}

The code for the activity (For simplicity and as a shortcut i did this, you can also specify it in the xml and just setContentView):

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;

/**
 * @author Atrix1987
 *
 */
public class SampleActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        CustomView cv = new CustomView(getApplicationContext());
        cv.setBackgroundColor(Color.WHITE);
        setContentView(cv, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
    }

}

Do explore the developer site links for custom views, for more insight.

Hope this helps.

PFB the screenshotThe screenshot from the sample i ran