I have a TextView in ScrollView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/parentLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ScrollView
android:id="#+id/textAreaScroller"
android:layout_width="400px"
android:layout_height="200px"
android:layout_x="0px"
android:layout_y="25px"
android:fadeScrollbars="false"
android:scrollbarSize="3px"
android:scrollbarStyle="insideOverlay" >
<TextView
android:id="#+id/scrapbook"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="" />
</ScrollView>
<Button
android:id="#+id/upBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Up" />
<Button
android:id="#+id/downBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Down" />
<ImageView
android:id="#+id/imageView"
android:layout_width="400px"
android:layout_height="200px"
/>
</LinearLayout>
TextView is has a lot of text that's why is scrollable. I need to draw the current visible content in TextView to Bitmap. For testing purposes I display this bitmap in ImageView. I have the following code:
public class TextviewToImageActivity extends Activity {
private TextView textView;
private ScrollView textAreaScroller;
private ImageView imageView;
private Handler mHandler;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mHandler = new Handler();
imageView = (ImageView) findViewById(R.id.imageView);
textAreaScroller = (ScrollView) findViewById(R.id.textAreaScroller);
textView = (TextView) findViewById(R.id.scrapbook);
textView.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
imageView.setImageBitmap(loadBitmapFromView(textAreaScroller));
return false;
}
});
Button upBtn = (Button) findViewById(R.id.upBtn);
Button downBtn = (Button) findViewById(R.id.downBtn);
upBtn.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
scheduleScroller(upScroller);
imageView.setImageBitmap(loadBitmapFromView(textView));
} else if (event.getAction() == MotionEvent.ACTION_UP) {
mHandler.removeMessages(1);
}
return true;
}
});
downBtn.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
scheduleScroller(downScroller);
imageView.setImageBitmap(loadBitmapFromView(textView));
} else if (event.getAction() == MotionEvent.ACTION_UP) {
mHandler.removeMessages(1);
}
return true;
}
});
loadDoc();
}
private Runnable downScroller = new Runnable() {
public void run() {
textAreaScroller.scrollBy(0, 10);
scheduleScroller(downScroller);
}
};
private Runnable upScroller = new Runnable() {
public void run() {
textAreaScroller.scrollBy(0, -10);
scheduleScroller(upScroller);
}
};
private void scheduleScroller(Runnable scrollerJob) {
Message msg = Message.obtain(mHandler, scrollerJob);
msg.what = 1;
mHandler.sendMessageDelayed(msg, 10);
}
private static Bitmap loadBitmapFromView(View v) {
Bitmap b = Bitmap.createBitmap(400, 200, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
private void loadDoc() {
String s = "";
for (int x = 0; x <= 100; x++) {
s += "Line: " + String.valueOf(x) + "\n";
}
textView.setText(s);
textView.setMovementMethod(new ScrollingMovementMethod());
}
}
The problem is that once I scroll TextView (trigger TouchEvent) the Bitmap doesn't reflect the current content of TextView and instead always has only the beginning content of TextView (it doesn't matter what's the current scroll position). I updated post to provide working code - maybe it will work on sb's other device.
UPDATE
I also tried to check WarrenFaith idea by overriding onDraw in my custom TextView but it somehow still only draw the begining content of TextView:
public class MyTextView extends TextView {
private Bitmap mBitmap;
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyTextView(Context context) {
super(context);
}
public MyTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public Bitmap getBitmap() {
return mBitmap;
}
#Override
protected void onDraw(Canvas canvas) {
mBitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight()
, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(mBitmap);
super.onDraw(canvas);
super.onDraw(c);
}
}
Try to override the onDraw() method of the TextView should work. There you can create a bitmap based on the canvas parameter. Details can be found in my tutorial: How to create and save a screenshot from a SurfaceView
Update:
I fixed your issue:
The activity (I changed the Handler usage and removed some methods. Basically I shrinked the code a bit).
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.text.method.ScrollingMovementMethod;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.ImageView;
/**
* #author WarrenFaith
*/
public class TextToImageActivity extends Activity {
private MyTextView textView;
private ImageView imageView;
private boolean mRepeatDrawing = false;
private Handler mHandler;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.textview);
mHandler = new Handler();
imageView = (ImageView) findViewById(R.id.imageView);
textView = (MyTextView) findViewById(R.id.scrapbook);
Button upBtn = (Button) findViewById(R.id.upBtn);
Button downBtn = (Button) findViewById(R.id.downBtn);
upBtn.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
mRepeatDrawing = true;
mHandler.post(upScroller);
} else if (event.getAction() == MotionEvent.ACTION_UP) {
mRepeatDrawing = false;
}
return false;
}
});
downBtn.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
mRepeatDrawing = true;
mHandler.post(downScroller);
} else if (event.getAction() == MotionEvent.ACTION_UP) {
mRepeatDrawing = false;
}
return false;
}
});
loadDoc();
}
private Runnable downScroller = new Runnable() {
public void run() {
textView.scrollBy(0, 10);
imageView.setImageBitmap(textView.getBitmap());
if (mRepeatDrawing) {
mHandler.postDelayed(this, 10);
}
}
};
private Runnable upScroller = new Runnable() {
public void run() {
textView.scrollBy(0, -10);
imageView.setImageBitmap(textView.getBitmap());
if (mRepeatDrawing) {
mHandler.postDelayed(this, 10);
}
}
};
private void loadDoc() {
String s = "";
for (int x = 0; x <= 100; x++) {
s += "Line: " + String.valueOf(x) + "\n";
}
textView.setText(s);
textView.setMovementMethod(new ScrollingMovementMethod());
}
}
The custom textview: Important: the trick was to get the scrolling position!
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.widget.TextView;
/**
* #author WarrenFaith
*/
public class MyTextView extends TextView {
private Bitmap mBitmap;
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyTextView(Context context) {
super(context);
}
public MyTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public Bitmap getBitmap() {
return mBitmap;
}
#Override
protected void onDraw(Canvas canvas) {
mBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(mBitmap);
c.translate(0, -getScrollY());
super.onDraw(c);
super.onDraw(canvas);
}
}
The xml: (I removed the ScrollView and let the TextView handle the scrolling)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/parentLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.testproject.MyTextView
android:id="#+id/scrapbook"
android:layout_width="400px"
android:layout_height="200px"
android:scrollbars="vertical"
android:scrollbarSize="3px"
android:text=""
android:background="#0000ff" />
<Button
android:id="#+id/upBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Up" />
<Button
android:id="#+id/downBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Down" />
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Related
My Issue is that I have a LinearLayout that I am inflating at runtime to a LinearLayout inside ScrollView.
This is the main_activity.xml
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/controlLayoutCV"
android:layout_alignParentStart="true"
android:layout_below="#+id/toolLayoutCV">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="#dimen/dp5"
android:paddingLeft="#dimen/dp7"
android:paddingRight="#dimen/dp7"
android:paddingTop="#dimen/dp5">
<android.support.v7.widget.CardView
android:id="#+id/questionQuizCV"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardElevation="#dimen/dp2">
<com.emedicoz.app.CustomViews.JustifiedTextView
android:id="#+id/questionQuizTV"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="#dimen/dp5"
android:text="" />
</android.support.v7.widget.CardView>
<LinearLayout
android:id="#+id/quizQuestionLL"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/questionQuizCV"
android:layout_marginTop="#dimen/dp5"
android:orientation="vertical"
android:padding="#dimen/dp5" />
</RelativeLayout>
</ScrollView>
& this is the item_layout.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mcqlayout_LL"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="#dimen/dp5"
android:minHeight="30dp"
android:orientation="horizontal"
android:paddingBottom="#dimen/dp7"
android:paddingTop="#dimen/dp7">
<TextView
android:id="#+id/optioniconTV"
android:layout_width="#dimen/dp40"
android:layout_height="#dimen/dp40"
android:background="#drawable/circle_bg"
android:gravity="center"
android:padding="#dimen/dp3"
android:text="A"
android:textSize="#dimen/sub_heading_text_size" />
<com.emedicoz.app.CustomViews.JustifiedTextView
android:id="#+id/optionTextTV"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="#dimen/dp10" />
</LinearLayout>
This is the CustomTextView that I have created to show the HTML content directly. The JustifiedTextView.class is
public class JustifiedTextView extends WebView {
private String text = "";
private int textSize = 12;
private int backgroundColor = Color.TRANSPARENT;
public JustifiedTextView(Context context, AttributeSet attrs) {
super(context, attrs);
this.setWebChromeClient(new WebChromeClient() {});
}
public void setText(String s) {
this.text = s;
reloadData();
}
#SuppressLint("NewApi")
private void reloadData() {
// loadData(...) has a bug showing utf-8 correctly. That's why we need to set it first.
this.getSettings().setDefaultTextEncodingName("utf-8");
// this.loadData(String.format(core,textColor,textSize,text), "text/html","utf-8");
this.loadData(text, "text/html", "utf-8");
// set WebView's background color *after* data was loaded.
super.setBackgroundColor(backgroundColor);
// Hardware rendering breaks background color to work as expected.
// Need to use software renderer in that case.
if (android.os.Build.VERSION.SDK_INT >= 11)
this.setLayerType(WebView.LAYER_TYPE_SOFTWARE, null);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
public void setTextSize(int textSize) {
this.textSize = textSize;
reloadData();
}
}
I have tried All of the solutions mentioned below.
Disable WebView touch events in Android
Already tried to set the android:descendantFocusability="blocksDescendants" to ScrollView
Why the click Event of LinearLayout does not fire when making click on WebView?
This is the way I am inflating the Layout and handle the click event.
private LinearLayout initAnswerMCViews(String text, String questions, Questions questionsModel) {
LinearLayout view = (LinearLayout) View.inflate(activity, R.layout.mcq_quiz, null);
answerTV = (JustifiedTextView) view.findViewById(R.id.optionTextTV);
optionIconTV = (TextView) view.findViewById(R.id.optioniconTV);
mcqItemLL = (LinearLayout) view.findViewById(R.id.mcqlayout_LL);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
lp.setMargins(3, 3, 3, 3);
mcqItemLL.setLayoutParams(lp);
if (questionsModel.isAnswered()) {
String[] answer = questionsModel.getUser_answer().split(",");
for (int i = 0; i < answer.length; i++) {
if (answer[i].equals(text)) {
answerTV.setText(questions);
optionIconTV.setText(text);
optionIconTV.setBackgroundResource(R.drawable.circle_bg_true);
} else {
answerTV.setText(questions);
optionIconTV.setText(text);
}
}
} else {
answerTV.setText(questions);
optionIconTV.setText(text);
}
mcqItemLL.setTag(R.id.questions, optionIconTV.getText().toString());
mcqItemLL.setTag(R.id.optionsAns, mcqItemLL);
mcqItemLL.setOnClickListener(optionClickListener);
viewArrayList.add(mcqItemLL);
return view;
}
Why the click is not get listen when clicked on the WebView part in the Layout?
I finally found the issue.
It is basically the issue of conflicting Touch Event of both parent Scrollview and CustomWebView.
So, by using the new classes that itself overriding the ClickListener and TouchListener.
package com.app.CustomViews;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
public class TestSeriesOptionWebView extends WebView implements GestureDetector.OnGestureListener {
private boolean check = false;
class LongClick implements OnLongClickListener {
final /* synthetic */ TestSeriesOptionWebView testSeriesOptionWebView;
LongClick(TestSeriesOptionWebView testSeriesOptionWebView) {
this.testSeriesOptionWebView = testSeriesOptionWebView;
}
public boolean onLongClick(View view) {
return true;
}
}
public TestSeriesOptionWebView(Context context) {
super(context);
handleClick();
}
public TestSeriesOptionWebView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
handleClick();
}
public TestSeriesOptionWebView(Context context, AttributeSet attributeSet, int i) {
super(context, attributeSet, i);
handleClick();
}
private void handleClick() {
setFocusable(false);
/*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
setLayerType(View.LAYER_TYPE_HARDWARE, null);
} else {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}*/
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
setVerticalScrollBarEnabled(false);
setBackgroundColor(0);
setHapticFeedbackEnabled(false);
setOnLongClickListener(new LongClick(this));
}
public void setDisableWebViewTouchListener(boolean z) {
this.check = z;
}
public boolean onTouchEvent(MotionEvent motionEvent) {
if (this.check) {
return false;
}
return super.onTouchEvent(motionEvent);
}
public boolean canScrollHorizontal(int i) {
int computeHorizontalScrollOffset = computeHorizontalScrollOffset();
int computeHorizontalScrollRange = computeHorizontalScrollRange() - computeHorizontalScrollExtent();
if (computeHorizontalScrollRange == 0) {
return false;
}
if (i < 0) {
if (computeHorizontalScrollOffset <= 0) {
return false;
}
return true;
} else if (computeHorizontalScrollOffset >= computeHorizontalScrollRange - 1) {
return false;
} else {
return true;
}
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
public boolean onDown(MotionEvent motionEvent) {
return true;
}
public void onShowPress(MotionEvent motionEvent) {
}
public boolean onSingleTapUp(MotionEvent motionEvent) {
return false;
}
public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent2, float f, float f2) {
return f != 0.0f;
}
public void onLongPress(MotionEvent motionEvent) {
}
public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent2, float f, float f2) {
return true;
}
}
If anybody faces this type of issue, then Use this Custom Class TestSeriesOptionWebView.class.
I have a next problem, which happens in 2 cases:
First case.
1). I have some custom veiw which draw photos on it with different opacity. here is method MyView.onDraw:
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.getClipBounds(clipRect);
int i1 = Math.min(testColors.length-1, (int)Math.floor(posX/PHOTO_DISTANCE));
int c1 = testColors[Math.max(0, i1)];
int i2 = Math.min(testColors.length-1, (int)Math.ceil(posX/PHOTO_DISTANCE));
int c2 = testColors[Math.max(0, i2)];
paint.setColor(c1);
float r = (255f/PHOTO_DISTANCE*posX)%255;
paint.setAlpha(255);
if(photoA != null){//bitmap != null
bitmapRect.set(0, 0, photoA.getWidth(), photoA.getHeight());
canvas.drawBitmap(photoA, bitmapRect, clipRect, paint);
}
paint.setAlpha((int)(r));
if(photoB != null){//bitmap != null
bitmapRect.set(0, 0, photoB.getWidth(), photoB.getHeight());
canvas.drawBitmap(photoB, bitmapRect, clipRect, paint);
}
}
testColors - array of colors(int);
photoA, photoB - bitmaps;
i1, i2 - image indexes;
c1, c2 - colors. they are not importatant.
I added this view to FrameView:
viewHolder.myFrame.addView(viewHolder.myView, 0);
And in this FrameView I have some clickable RelativeLayout's:
<com.app.custom.view.ClickableRelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/share_action_container"
app1:pressedStateColor="#color/app_pressed_default"
app1:unpressedStateColor="#color/color_white"
android:background="#color/transparent"
android:layout_centerHorizontal="true">
<RelativeLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/circle_background"
android:id="#+id/share_icon"
android:layout_centerHorizontal="true">
<ImageView
android:id="#+id/img_share"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:tag="icon"
android:src="#drawable/ic_share"/>
</RelativeLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_below="#id/share_icon"
android:text="Share"
android:layout_marginTop="3dp"
android:shadowColor="#color/text_shadow"
android:shadowDx="#integer/shadowDX"
android:shadowDy="#integer/shadowDY"
android:shadowRadius="#integer/shadowRadius"
android:background="#color/transparent"
android:layout_centerHorizontal="true"
android:textSize="#dimen/icon_text_size"
android:tag="text"
android:textColor="#android:color/white"
android:id="#+id/txt_share_action"/>
</com.app.custom.view.ClickableRelativeLayout>
Here is a Java code of ClickableRelativeLayout:
public class ClickableRelativeLayout extends RelativeLayout implements View.OnTouchListener {
private ViewHolder viewHolder;
private int pressedStateColor;
private int unpressedStateColor;
private final int DEFAULT_PRESSED_STATE_COLOR;
private final int DEFAULT_UNPRESSED_STATE_COLOR;
public ClickableRelativeLayout(Context context) {
super(context);
DEFAULT_PRESSED_STATE_COLOR = context.getResources().getColor(R.color.app_pressed_default);
DEFAULT_UNPRESSED_STATE_COLOR = context.getResources().getColor(R.color.app_blue_without_transparent);
setup();
initColors(context, null);
}
public ClickableRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
DEFAULT_PRESSED_STATE_COLOR = context.getResources().getColor(R.color.app_pressed_default);
DEFAULT_UNPRESSED_STATE_COLOR = context.getResources().getColor(R.color.app_blue_without_transparent);
setup();
initColors(context, attrs);
}
public ClickableRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
DEFAULT_PRESSED_STATE_COLOR = context.getResources().getColor(R.color.app_pressed_default);
DEFAULT_UNPRESSED_STATE_COLOR = context.getResources().getColor(R.color.app_blue_without_transparent);
setup();
initColors(context, attrs);
}
private void setup(){
setOnTouchListener(this);
}
private void initColors(Context context, AttributeSet attrs){
if(attrs != null) {
TypedArray styledAttributes = context.obtainStyledAttributes(attrs, R.styleable.ClickableRelativeLayout);
pressedStateColor = styledAttributes.getColor(R.styleable.ClickableRelativeLayout_pressedStateColor,
DEFAULT_PRESSED_STATE_COLOR);
unpressedStateColor = styledAttributes.getColor(R.styleable.RowLayout_android_verticalSpacing,
DEFAULT_UNPRESSED_STATE_COLOR);
styledAttributes.recycle();
}else{
pressedStateColor = DEFAULT_PRESSED_STATE_COLOR;
unpressedStateColor = DEFAULT_UNPRESSED_STATE_COLOR;
}
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
viewHolder = new ViewHolder(
(TextView) findViewWithTag("text"),
(ImageView) findViewWithTag("icon")
);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
if (hasOnClickListeners()) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
select();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
unSelect();
break;
}
}
}
return false;
}
private void select(){
if(isInitializedCorrect()){
final int color = pressedStateColor;
viewHolder.text.setTextColor(color);
ImageHelper.INSTANCE.applyColorFilterToImage(viewHolder.icon.getDrawable(), color);
}
}
private void unSelect(){
if(isInitializedCorrect()){
final int color = unpressedStateColor;
viewHolder.text.setTextColor(color);
viewHolder.icon.setColorFilter(color);
}
}
private boolean isInitializedCorrect(){
return viewHolder != null && viewHolder.icon != null && viewHolder.text != null;
}
private class ViewHolder{
ImageView icon;
TextView text;
public ViewHolder(TextView text, ImageView icon) {
this.text = text;
this.icon = icon;
}
}
}
And when I clicked on this layout, background of MyView shrinks, and sets to this ClickableRelativeLayout:
And Second case.
I have some text view on same frame, it is invisible by default, and when you scrolled 10 photos, I apply AlphaAnimation for this TextView and it draws slowly. Here is a code of alpha animation:
AlphaAnimation animation1 = new AlphaAnimation(0.0f, 1.0f);
animation1.setDuration(1300);
animation1.setFillAfter(true);
//here is my TextView
viewHolder.gotItView.setVisibility(View.VISIBLE);
viewHolder.gotItView.startAnimation(animation1);
And happens the same this. On background of this TextView appears content of MyView
I am developing an android application, in this one page after filling up the details, at the end of the page i need to place some imageview or fragement in which user can able to sign thier signature it by touching. so that i can save that signature as image while clicking submit.
i have googled about this but i did not get any tutorial kind of thing to start.
Please help me out from this or share some link if you guys know.
Thanks in Advance,
Srikanth A
this is my class file,
package com.example.test_signature;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable.Callback;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
public class SignatureView extends SurfaceView implements OnTouchListener, Callback, android.view.SurfaceHolder.Callback {
public SignatureView(Context context) {
super(context);
init();
}
public SignatureView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init(){
this.setBackgroundColor(Color.WHITE);
mPaint = new Paint();
mPaint.setColor(Color.BLACK);
mPaint.setStrokeWidth(3);
this.setOnTouchListener(this);
this.getHolder().addCallback(this);
}
public void setStrokeWidth(float width){
mPaint.setStrokeWidth(width);
this.invalidate();
}
public void setColor(int color){
mPaint.setColor(color);
this.invalidate();
}
public void clear(){
mDots = new ArrayList<List<Dot>>();
//To prevent an exception
mDots.add(new ArrayList<Dot>());
this.invalidate();
}
private List<List<Dot>> mDots = new ArrayList<List<Dot>>();
private class Dot{
public float X = 0;
public float Y = 0;
public Dot(float x, float y){
X = x;
Y = y;
}
}
#Override
public boolean onTouch(View view, MotionEvent event) {
//mLastActivity = Calendar.getInstance();
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
mDots.add(new ArrayList<Dot>());
mDots.get(mDots.size() - 1).add(new Dot(event.getX(), event.getY()));
this.invalidate();
break;
case MotionEvent.ACTION_UP:
mDots.get(mDots.size() - 1).add(new Dot(event.getX(), event.getY()));
this.invalidate();
break;
case MotionEvent.ACTION_MOVE:
mDots.get(mDots.size() - 1).add(new Dot(event.getX(), event.getY()));
this.invalidate();
break;
}
return true;
}
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
public void surfaceCreated(SurfaceHolder arg0) {
}
public void surfaceDestroyed(SurfaceHolder arg0) {
}
public Paint mPaint;
#Override
protected void onDraw(Canvas canvas) {
for(List<Dot> dots : mDots){
for(int i = 0; i < dots.size(); i++){
if(i - 1 == -1)
continue;
canvas.drawLine(dots.get(i - 1).X, dots.get(i - 1).Y, dots.get(i).X, dots.get(i).Y, mPaint);
}
}
}
public Bitmap getBitmap(){
Bitmap b = Bitmap.createBitmap(this.getWidth(), this.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
this.draw(c);
return b;
}
public boolean exportFile(String pathString, String fileString){
File path = new File(pathString);
path.mkdirs();
if(!fileString.toLowerCase(Locale.ENGLISH).contains(".png")){
fileString += ".png";
}
File file = new File(path, fileString);
FileOutputStream out;
try {
out = new FileOutputStream(file);
this.getBitmap().compress(Bitmap.CompressFormat.PNG, 90, out);
return true;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
}
this is My XML file in which i have created the view for the user to put a signature.
<RelativeLayout 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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".SignatureView" >
<View
android:id="#+id/id"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<com.example.test_signature.SignatureView
android:id="#+id/signature"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:height="18dp"
android:width="18dp" />
</RelativeLayout>
i have created this sample to test the signature functionality. But whenever i run this code, my application get crashes. Anyone please help me out. I think i have done a mistake in my XML.
#FabianCook : pla look out the code i have pasted. I'hv followed your procedure oly. but can u pls tel me wats the problem in the code ?
I have edited my XML file as you suggested, but still my application getting crashes whenever i open.
<RelativeLayout 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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".SignatureView" >
<View
android:id="#+id/id"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.example.test_signature.SignatureView
android:id="#+id/signature"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
public class SignatureView extends SurfaceView implements OnTouchListener, Callback {
public SignatureView(Context context) {
super(context);
init();
}
public SignatureView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init(){
this.setBackgroundColor(Color.WHITE);
mPaint = new Paint();
mPaint.setColor(Color.BLACK);
mPaint.setStrokeWidth(3);
this.setOnTouchListener(this);
this.getHolder().addCallback(this);
}
public void setStrokeWidth(float width){
mPaint.setStrokeWidth(width);
this.invalidate();
}
public void setColor(int color){
mPaint.setColor(color);
this.invalidate();
}
public void clear(){
mDots = new ArrayList<List<Dot>>();
//To prevent an exception
mDots.add(new ArrayList<Dot>());
this.invalidate();
}
private List<List<Dot>> mDots = new ArrayList<List<Dot>>();
private class Dot{
public float X = 0;
public float Y = 0;
public Dot(float x, float y){
X = x;
Y = y;
}
}
#Override
public boolean onTouch(View view, MotionEvent event) {
//mLastActivity = Calendar.getInstance();
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
mDots.add(new ArrayList<Dot>());
mDots.get(mDots.size() - 1).add(new Dot(event.getX(), event.getY()));
this.invalidate();
break;
case MotionEvent.ACTION_UP:
mDots.get(mDots.size() - 1).add(new Dot(event.getX(), event.getY()));
this.invalidate();
break;
case MotionEvent.ACTION_MOVE:
mDots.get(mDots.size() - 1).add(new Dot(event.getX(), event.getY()));
this.invalidate();
break;
}
return true;
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
#Override
public void surfaceCreated(SurfaceHolder arg0) {
}
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
}
public Paint mPaint;
#Override
protected void onDraw(Canvas canvas) {
for(List<Dot> dots : mDots){
for(int i = 0; i < dots.size(); i++){
if(i - 1 == -1)
continue;
canvas.drawLine(dots.get(i - 1).X, dots.get(i - 1).Y, dots.get(i).X, dots.get(i).Y, mPaint);
}
}
}
public Bitmap getBitmap(){
Bitmap b = Bitmap.createBitmap(this.getWidth(), this.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
this.draw(c);
return b;
}
public boolean exportFile(String pathString, String fileString){
File path = new File(pathString);
path.mkdirs();
if(!fileString.toLowerCase(Locale.ENGLISH).contains(".png")){
fileString += ".png";
}
File file = new File(path, fileString);
FileOutputStream out;
try {
out = new FileOutputStream(file);
this.getBitmap().compress(Bitmap.CompressFormat.PNG, 90, out);
return true;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
}
I think the code explains its self
This code takes care of everything. Has some nice little functions for different things like saving the image to a file etc.
Place this in one of your packages, and then in your XML file replace
<View android:id="#+id/id"/>
with
<package.name.SignatureView android:id="#+id/id"/>
USAGE
Create a new class in your package called SignatureView, delete everything in this file except for the first line, you should be left with package your.package.name
On the third line paste the code above and press Ctrl-Shift-O and it will import everything you need.
Save this file and then build your project.
In your XML file use:
<your.package.name.SignatureView
android:id="#+id/signature"
android:width="match_parent"
android:height="match_parent"/>
Save this and build your project.
In your activity you can use:
SignatureView mSignature;
mSignature = (SignatureView) this.findViewById(R.id.signature);
And then access the functions you need to save the signature to a file:
mSignature.exportFile("/mnt/sdcard/", "signaturefile.png");
hope this code helps you:)
esign_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.gesture.GestureOverlayView
android:id="#+id/signaturePad"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="5"
android:background="#android:color/white"
android:clickable="false"
android:eventsInterceptionEnabled="true"
android:fadeEnabled="false"
android:gestureColor="#0000ff"
android:gestureStrokeLengthThreshold="0.1"
android:gestureStrokeType="multiple"
android:longClickable="false"
android:orientation="vertical"
android:uncertainGestureColor="#000000"
android:splitMotionEvents="true"
android:fadeOffset="10000000">
</android.gesture.GestureOverlayView>
<RelativeLayout
android:id="#+id/rellay_esign_donebutton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
>
<Button
android:id="#+id/DoneButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Done" />
<Button
android:id="#+id/ClearButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Clear" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
Esignature.java
public class Esignature extends Activity {
GestureOverlayView gestureView;
String path;
File file;
Bitmap bitmap;
public boolean gestureTouch=false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.esign_main);
Button donebutton = (Button) findViewById(R.id.DoneButton);
donebutton.setText("Done");
Button clearButton = (Button) findViewById(R.id.ClearButton);
clearButton.setText("Clear");
path=Environment.getExternalStorageDirectory()+"/signature.png";
file = new File(path);
file.delete();
gestureView = (GestureOverlayView) findViewById(R.id.signaturePad);
gestureView.setDrawingCacheEnabled(true);
gestureView.setAlwaysDrawnWithCacheEnabled(true);
gestureView.setHapticFeedbackEnabled(false);
gestureView.cancelLongPress();
gestureView.cancelClearAnimation();
gestureView.addOnGestureListener(new OnGestureListener() {
#Override
public void onGesture(GestureOverlayView arg0, MotionEvent arg1) {
// TODO Auto-generated method stub
}
#Override
public void onGestureCancelled(GestureOverlayView arg0,
MotionEvent arg1) {
// TODO Auto-generated method stub
}
#Override
public void onGestureEnded(GestureOverlayView arg0, MotionEvent arg1) {
// TODO Auto-generated method stub
}
#Override
public void onGestureStarted(GestureOverlayView arg0,
MotionEvent arg1) {
// TODO Auto-generated method stub
if (arg1.getAction()==MotionEvent.ACTION_MOVE){
gestureTouch=false;
}
else
{
gestureTouch=true;
}
}});
donebutton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
try {
bitmap = Bitmap.createBitmap(gestureView.getDrawingCache());
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
fos = new FileOutputStream(file);
// compress to specified format (PNG), quality - which is
// ignored for PNG, and out stream
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
if(gestureTouch==false)
{
setResult(0);
finish();
}
else
{
setResult(1);
finish();
}
}
});
clearButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
gestureView.invalidate();
gestureView.clear(true);
gestureView.clearAnimation();
gestureView.cancelClearAnimation();
}
});
}
}
This is my updated code. It doesn't detect movement at all now. Maybe I shouldn't be making each Image an instance? Basically I want to user to be able to swipe through all the images to make them dissapear.
Thanks for all the help.
package com.picomputing.mythirdapplication;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
/**
* Created by Paul on 8/13/13.
*/
public class Pin extends ImageView implements View.OnTouchListener {
boolean isPinDown;
public Pin(Context context) {
super(context);
this.isPinDown = false;
}
public Pin(Context context, AttributeSet attrs) {
super(context, attrs);
this.isPinDown = false;
}
public Pin(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.isPinDown = false;
}
public boolean pinDown() {
return this.isPinDown;
}
public void setPinDown() {
this.isPinDown = true;
}
public void setPinUp() {
this.isPinDown = false;
}
public void togglePin() {
if (isPinDown == false)
{
isPinDown = true;
this.setImageResource(Color.TRANSPARENT);
}
else
{
isPinDown = false;
this.setImageResource(R.drawable.pin);
}
}
#Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_MOVE:
int x = (int) event.getX(); //--relative to mLayout--
int y = (int) event.getY(); //--relative to mLayout--
Rect r = new Rect();
view.getHitRect(r);
if(r.contains(x,y) && view instanceof ImageView){
togglePin();
}
}
return true;
}
}
You need to listen and consume ACTION_MOVE events, for the parent view of whatever you are trying to change.
Here's an example with a couple of ImageViews in a LinerLayout as a parent:
public class test extends Activity {
LinearLayout mLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLayout = new LinearLayout(this);
mLayout.setOrientation(LinearLayout.VERTICAL);
for(int i = 0 ; i < 5; i++){
ImageView iv = new ImageView(this);
iv.setImageResource(android.R.drawable.ic_dialog_info);
mLayout.addView(iv);
}
setContentView(mLayout);
mLayout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_MOVE:
int x = (int) event.getX(); //--relative to mLayout--
int y = (int) event.getY(); //--relative to mLayout--
Rect r = new Rect();
for(int i = 0 ; i < mLayout.getChildCount(); i++){
View v = mLayout.getChildAt(i);
v.getHitRect(r);
if(r.contains(x,y) && v instanceof ImageView){
((ImageView) v).setImageResource(android.R.drawable.ic_dialog_alert);
}
}
}
return true; //-- this means that view is interested in more events of all kinds--
}
});
}
}
I hope I didn't misunderstand your question
but if what you want to do is to prevent multitoch on the image you can add this attribute
android:splitMotionEvents="false"
in the xml in the parent view of the imageview. for example :
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:splitMotionEvents="false"
>
// YOUR IMAGE VIEW HERE
</LinearLayout>
if you have any question feel free to ask in the comment :)
there are mainly three events on OnTouch action_down,Action_move and Action_up. do your coding on action down event i.e when user has touched your view. see the example here:
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
if (arg1.getAction()==MotionEvent.ACTION_DOWN) {
//write your code here
}
else {
if (arg1.getAction()==MotionEvent.ACTION_MOVE){
do things
}
else {
if (arg1.getAction()==MotionEvent.ACTION_UP){
do things
}
}
}
This is my xml file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/LinearLayout0"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CanvasActivity"
android:baselineAligned="false">
<LinearLayout
android:id="#+id/LinearLayout1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#f9dfcb">
</LinearLayout>
<LinearLayout
android:id="#+id/LinearLayout2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="3"
android:background="#000000"
>
</LinearLayout>
</LinearLayout>
My activity code
import android.app.Activity;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.LinearLayout;
import android.widget.Toast;
public class CanvasActivity extends Activity {
private GestureDetector gestureDetector;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_canvas);
gestureDetector = new GestureDetector(this, new GestureListener());
LinearLayout LinearLayout1=(LinearLayout)findViewById(R.id.LinearLayout1);
LinearLayout1.setOnTouchListener(new OnTouchListener(){
public boolean onTouch(View v, MotionEvent event){
if (gestureDetector.onTouchEvent(event))
{
return true;
}
return false;
}
});
/*********EDITED*******/
LinearLayout LinearLayout2=(LinearLayout)findViewById(R.id.LinearLayout2);
int width=LinearLayout2.getWidth();
int height=LinearLayout2.getHeight();
LinearLayout2.addView(new Canvasview(this), width, height) ;
LinearLayout2.setOnTouchListener(new OnTouchListener(){
public boolean onTouch(View v, MotionEvent event){
Canvasview cv= new Canvasview(v.getContext());
cv.onTouchEvent(event);
return true;
}
});
}
//discerning swipes
class GestureListener extends SimpleOnGestureListener
{
private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2,
float velocityX, float velocityY)
{
if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE &&
Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
//From Right to Left
Toast.makeText(CanvasActivity.this, "Left Swipe", Toast.LENGTH_SHORT).show();
return true;
}
else if(e1.getY() - e2.getY() > SWIPE_MIN_DISTANCE &&
Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) {
//From Bottom to Top
Toast.makeText(CanvasActivity.this, "Top Swipe", Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
#Override
public boolean onDown(MotionEvent e)
{
return true;
}
}
}
My Canvasview looks like this
public class Canvasview extends SurfaceView implements SurfaceHolder.Callback{
private int width, height;
private Paint textPaint = new Paint();
private Paint touchPaint = new Paint();
private int colors[] = new int[10];
public Canvasview(Context context) {
super(context);
SurfaceHolder holder = getHolder();
holder.addCallback(this);
setFocusable(true); // make sure we get key events
setFocusableInTouchMode(true); // make sure we get touch events
init();
}
private void init()
{
textPaint.setColor(Color.WHITE);
colors[0] = Color.RED;
touchPaint = new Paint();
touchPaint.setColor(colors[0]);
}
public boolean onTouchEvent(MotionEvent event)
{
Canvas c = getHolder().lockCanvas();
if (c != null)
{
if (event.getAction() == MotionEvent.ACTION_UP)
{
// clear everything
}
else
{
int xval = (int)event.getX();
int yval = (int)event.getY();
drawCircle(xval,yval,touchPaint,c);
}
getHolder().unlockCanvasAndPost(c);
}
return true;
}
public void clear(Canvas c){
c = getHolder().lockCanvas();
c.drawColor(Color.BLACK);
getHolder().unlockCanvasAndPost(c);
}
private void drawCircle(int x, int y, Paint paint, Canvas c)
{
c.drawCircle(x, y, 2, paint);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){
Canvas c = getHolder().lockCanvas();
if (c != null)
{
// clear screen
c.drawColor(Color.BLACK);
getHolder().unlockCanvasAndPost(c);
}
}
#Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
}
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
}
}
I need the canvas only in linearlayout2, but the canvas occupies the entire screen. I am not sure where I am going wrong.
EDIT:
Well I did few changes and I get the Canvasview in linearlayout2, the ontouchevents of Canvasview detects the touch events but in Canvasview public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) method does not initialize a canvas and therefore it is always null. To draw I need the canvas not to be null. Any help is appreciated
set hardcode value of layout_width for first linear layout and try again
The first problem is that you want to get height and width of a view, that hasn't been drawn yet in onCreate():
int width=LinearLayout2.getWidth();
int height=LinearLayout2.getHeight();
A possible solution for that is to set static values or use a ViewTreeObserver (https://stackoverflow.com/search?q=get+measured+width+height+android).
The other problem you might have is that linear layout doesn't call onTouch() method. You may try using a scrolling view(scrollview for example) instead of linear layout.
I changed my xml file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/LinearLayout0"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context=".CanvasActivity"
android:baselineAligned="false">
<View
android:id="#+id/view0"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="3"
android:background="#f9dfcb"
/>
<com.multitel.testwidget.Canvasview
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/surfaceView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
</com.multitel.testwidget.Canvasview>
</LinearLayout>
and changed the constructor in Canvasview to
public Canvasview(Context context, AttributeSet attrs)
{
super(context, attrs);
// TODO Auto-generated constructor stub
SurfaceHolder holder = getHolder();
holder.addCallback(this);
setFocusable(true); // make sure we get key events
setFocusableInTouchMode(true); // make sure we get touch events
init();
holder.getSurface();
}
And i could draw on the canvas!!