Limit to number of touches on Android? - android

I have a small test app on Android that is meant to test tracking multitouch input, but I am only ever getting two touches at the same time on my Evo. Does anyone know if this is a limitation to Android or the hardware?
By the way, here's my test class so you can try it out yourself.
import java.util.HashMap;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.view.MotionEvent;
import android.view.View;
public class PressureView extends View
{
private HashMap<Integer, Spot> mSpots = new HashMap<Integer, Spot>();
private final int[] mColors;
private final Paint mPaint;
public PressureView(Context context)
{
super(context);
mPaint = new Paint();
mPaint.setStyle(Style.FILL);
mColors = new int[]{Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.MAGENTA};
}
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
canvas.drawColor(Color.WHITE);
for(int id : mSpots.keySet())
{
Spot spot = mSpots.get(id);
mPaint.setColor(spot.Color);
canvas.drawCircle(spot.X, spot.Y, spot.Pressure*500, mPaint);
}
}
#Override
public boolean onTouchEvent(MotionEvent event)
{
System.out.println("************************** " + event.getPointerCount() + " Pointers");
for(int i = 0; i < event.getPointerCount(); i++)
{
int id = event.getPointerId(i);
Spot spot = null;
if(mSpots.containsKey(id))
{
spot = mSpots.get(id);
}
else
{
spot = new Spot();
spot.Color = mColors[mSpots.size()];
}
if(event.getAction() == MotionEvent.ACTION_UP) spot.Pressure = 0;
else spot.Pressure = event.getPressure(id);
spot.X = event.getX(id);
spot.Y = event.getY(id);
mSpots.put(id, spot);
}
invalidate();
return true;
}
private class Spot
{
public float X, Y, Pressure;
public int Color;
}
}

It seems that currently all HTC devices only can 2 finger multi-touch, but the Android SDK supports more fingers. E.g. the Galaxy S i9000 has support for more http://www.youtube.com/watch?v=KRCDRXYJBCY .

Related

Probable android memory leak

I have this android project, can not identify why it is eating up RAM ? Note there is no processing just RAM being filled in. I have read Android RAM issues and how to solve, but can't make out what to do. I am new to both android and java.
Noticed just now (in Android Monitor - RAM) my app is using only 4MB of memory.
If anyone tries to run (please do - MainActivity is launcher and MyCanvas is just a class used as View) this, i can use speed variable as high as 100 (even more maybe), make thread call back in 10ms or even more frequent - it creates no problem. But as soon as I touch and move garbage collector comes pauses everything.
MyCanvas.java (used as view)
package com.abc.mygraphics;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
import java.util.Random;
import android.os.Handler;
public class MyCanvas extends View {
public static Paint paint;
//public static int n = 5000;
public static int N = 100, particleSize = 3;
public static int height, width;
public static float[][] pos = new float[N][2];
public static float[][] pos0 = new float[N][2];
//public static float distX, distY, dist;
Handler handler = new Handler();
public static int speed = 1;
public static int gravityX, gravityY;
public static Random random = new Random();
public static int[] colorList = new int[10];
public static int sphereSize = 100, M = 10;
public static float[] distance = new float[N];
public static int[][] gravity = new int[N][2];
public static boolean[] direction = new boolean[N];
public static int[] moved = new int[N];
public MyCanvas(Context context) {
super(context);
width = MainActivity.sharedPreferences.getInt("screenX", 200);
height = MainActivity.sharedPreferences.getInt("screenY", 200);
colorList = new int[]{Color.RED, 0xffff4000, 0xffffff00, 0xff40ff00, 0xff00ff00, 0xff00ff80, 0xff0080ff, 0xff0000ff, 0xffbf00ff, 0xffff0040};
paint = new Paint();
paint.setColor(Color.GRAY);
int i;
for (i = 0; i < N; i++) {
pos[i][0] = random.nextInt(width);
pos[i][1] = random.nextInt(height);
pos0[i][0] = pos[i][0];
pos0[i][1] = pos[i][1];
moved[i] = 0;
direction[i] = true;
}
final Runnable r = new Runnable() {
public void run() {
invalidate();
handler.postDelayed(this, 100);
}
};
handler.postDelayed(r, 100);
}
public static void changeGravity(){
gravityX = MainActivity.sharedPreferences.getInt("x",200);
gravityY = MainActivity.sharedPreferences.getInt("y",200);
// gravityY -= 68;
for(int i=0;i<N;i++){
calcDist(i);
}
}
#Override
public void onDraw(Canvas canvas){
int i;
int x; //remove at some poitnt
canvas.drawColor(Color.BLACK);
//canvas.drawCircle(gravityX,gravityY, 50, paint);
for(i=0;i<N;i++) {
setPosition(i);
x = random.nextInt(10);
paint.setColor(colorList[x]);
canvas.drawCircle(pos[i][0], pos[i][1], particleSize, paint);
}
}
public static void setPosition(int i){
// this is wrong
if(moved[i] >= (int)distance[i]/speed){
direction[i] = !direction[i];
setGravity(i);
}
else{
pos[i][0] = pos0[i][0] + speed*moved[i]*(gravity[i][0]- pos0[i][0])/distance[i];
pos[i][1] = pos0[i][1] + speed*moved[i]*(gravity[i][1]- pos0[i][1])/distance[i];
moved[i]++;
}
}
public static void calcDist(int i){
setGravity(i);
distance[i] = (float) Math.sqrt( Math.pow((gravity[i][0]-pos[i][0]),2) + Math.pow((gravity[i][1]-pos[i][1]),2) );
}
public static void setGravity(int i){
// do not forget to set pos0 in both cases
if(direction[i]){
gravity[i][0] = gravityX;
gravity[i][1] = gravityY;
}
else{
// make this biased on radius of sphere
gravity[i][0] = random.nextInt(width);
gravity[i][1] = random.nextInt(height);
}
pos0[i][0] = pos[i][0];
pos0[i][1] = pos[i][1];
moved[i]=0;
}
}
Main Activity.java
package com.abc.mygraphics;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.Window;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.TextView;
import com.abc.mygraphics.MyCanvas;
import org.w3c.dom.Text;
public class MainActivity extends AppCompatActivity {
//DrawingView dr = new DrawingView(this);
public static SharedPreferences sharedPreferences;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels;
sharedPreferences = getSharedPreferences( getPackageName() + "_preferences", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt("screenX",width);
editor.putInt("screenY", height);
editor.putInt("x", 200);
editor.putInt("y", 200);
editor.commit();
setContentView(new MyCanvas(this));
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// int x = (int)event.getX();
//int y = (int)event.getY();
int x = (int) event.getRawX();
int y = (int) event.getRawY();
//sharedPreferences = getSharedPreferences("CheckSharing",Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt("x", x);
editor.putInt("y", y);
editor.apply();
MyCanvas.changeGravity();
return false;
}
}
Got my problem.
I was trying to call my methods every time a touch event happens, this is something we can't do because when you drag your mouse there are literally thousands(possibly more) touch events happening.
Try understanding from code. In main activity we have our onTouch event listener which calls changeGravity() method which in turn calls calcDist() and setGravity() (from calcDist() ) . So thats a lot of garbage being generated and hence the GC comes in to play, it pauses the application and everything seems like hanged.
Solution - Just place the calcDist() call inside thread, so whatever be the vakue of gravity will come in effect in 10ms. This is something our emulator and phone are capable of, compared to what happens if we call from changeGravity() method.

Adding drawable image to background of canvas

I know its possible to paint the background of canvas using
mPaint = new Paint();
mPaint.setColor(Color.RED);
Im just wondering how to i set a permanent background for it. Ive tried using the xml file but nothing happens. Any ideas?
This is the source code of the project, ive been following a tutorial how to do it because im fairly unfamiliar with bitmaps.
Canvas Class
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
public class GameBoard extends View{
private int mFlagX = -1;
private int mFlagY = -1;
private Bitmap mBitmap = null;
private Bitmap nBitmap = null;
private Paint mPaint = null;
private boolean isFlagHidden = false;
private int mBoundX = -1;
private int mBoundY = -1;
//play with these values to make the app more or less challenging
public final int CLOSER = 50;
public final int CLOSE = 100;
public GameBoard(Context context, AttributeSet aSet) {
super(context, aSet);
//load our bitmap
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.star);
//create a paint brush
mPaint = new Paint();
mPaint.setColor(Color.RED);
}
#Override
public void onDraw(Canvas canvas) {
//initialize
if ((mFlagX < 1) || (mFlagY < 1)) {
mFlagX = (int) (getWidth() / 2) - mBitmap.getWidth() / 2;
mFlagY = (int) (getHeight() / 2) - mBitmap.getHeight() / 2;
mBoundX = (int)getWidth() - mBitmap.getWidth();
mBoundY = (int)getHeight() - mBitmap.getHeight();
}
//draw background
canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint);
//draw the flag
if (!isFlagHidden) {
canvas.drawBitmap(mBitmap, mFlagX, mFlagY, null);
}
}
public void hideTheFlag(){
//randomize flag location
mFlagX = (int) Math.ceil(Math.random() * mBoundX);
mFlagY = (int) Math.ceil(Math.random() * mBoundY);
isFlagHidden = true;
//force redraw
invalidate();
}
public void giveUp(){
isFlagHidden = false;
//force redraw
invalidate();
}
public Indicators takeAGuess(float x, float y) {
//this is our "warm" area
Rect prettyClose = new Rect(mFlagX - CLOSE, mFlagY - CLOSE, mFlagX+mBitmap.getWidth() + CLOSE, mFlagY+mBitmap.getHeight() + CLOSE);
//normalize
if (prettyClose.left < 0) prettyClose.left = 0;
if (prettyClose.top < 0) prettyClose.top = 0;
if (prettyClose.right > mBoundX) prettyClose.right = mBoundX;
if (prettyClose.bottom > mBoundY) prettyClose.bottom = mBoundY;
//this is our "hot" area
Rect reallyClose = new Rect(mFlagX - CLOSER, mFlagY - CLOSER, mFlagX+mBitmap.getWidth() + CLOSER, mFlagY+mBitmap.getHeight() + CLOSER);
//normalize
if (reallyClose.left < 0) reallyClose.left = 0;
if (reallyClose.top < 0) reallyClose.top = 0;
if (reallyClose.right > mBoundX) reallyClose.right = mBoundX;
if (reallyClose.bottom > mBoundY) reallyClose.bottom = mBoundY;
//this is the area that contains our flag
Rect bullsEye = new Rect(mFlagX, mFlagY, mFlagX+mBitmap.getWidth(), mFlagY+mBitmap.getHeight());
//check to see where on the board the user pressed
if (bullsEye.contains((int) x, (int)y)) {
//found it
isFlagHidden = false;
invalidate();
return Indicators.BULLSEYE;
} else if (reallyClose.contains((int) x, (int)y)) {
//hot
return Indicators.HOT;
} else if (prettyClose.contains((int)x, (int)y)) {
//warm
return Indicators.WARM;
} else {
//not even close
return Indicators.COLD;
}
}
}
Game Class
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.TextView;
public class FindTheStar extends Activity implements OnTouchListener, OnClickListener{
private GameBoard mGameBoard = null;
private boolean isFlagHidden = false;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_star);
mGameBoard = (GameBoard) findViewById(R.id.Hide_canvas);
mGameBoard.setOnTouchListener(this);
Button b = (Button) findViewById(R.id.the_button);
b.setOnClickListener(this);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
if (v.getId() == R.id.Hide_canvas) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (isFlagHidden) {
TextView tv = (TextView)findViewById (R.id.the_label);
switch (mGameBoard.takeAGuess(event.getX(), event.getY())) {
case BULLSEYE:
Button b = (Button) findViewById(R.id.the_button);
isFlagHidden = false;
b.setText("Go Hide!");
tv.setText("You found me!");
tv.setTextColor(Color.GREEN);
break;
case HOT:
tv.setText("You're hot!");
tv.setTextColor(Color.RED);
break;
case WARM:
tv.setText("Getting warm...");
tv.setTextColor(Color.YELLOW);
break;
case COLD:
tv.setText("You're cold.");
tv.setTextColor(Color.BLUE);
break;
}
}
}
return true;
}
return false;
}
#Override
public void onClick(View v) {
if (v.getId() == R.id.the_button) {
TextView tv = (TextView)findViewById (R.id.the_label);
tv.setText("");
Button b = (Button) findViewById(R.id.the_button);
isFlagHidden = !isFlagHidden;
if (isFlagHidden) {
b.setText("Can't find me?");
mGameBoard.hideTheFlag();
} else {
b.setText("Go Hide!");
mGameBoard.giveUp();
}
}
}
}
XML File
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="#+id/the_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:textSize="20sp"
android:layout_marginBottom="10dip"
android:text="Lets Play Hide and Seek!"/>
<Button
android:id="#+id/the_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:layout_marginBottom="10dip"
android:text="Go Hide!"/>
<app.autismapp.GameBoard
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/Hide_canvas"/>
</LinearLayout>
yes you can set your permanent background using xml layout..i done this by creating two class.
this is my code in MainACtivity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final BrushView view=new BrushView(this);
setContentView(R.layout.mylayout);//removed this one if the paint doesnt work
view.setBackgroundResource(R.drawable.background);//to set background
setContentView(view);// to display the background
and my second class
public class PaintView extends View {
private Paint paint = new Paint();
public LayoutParams params;
public PaintView(Context context) {
super(context);
paint.setAntiAlias(true);
paint.setColor(Color.BLUE);
i hope it gives you an idea

How to add Color Picker in Application?

I have developed an Application , which uses screen as a Slate and finger as a Chalk, which is working properly. But I want to use different color types for chalk.
Here is my Code:
MyDemo.java
package com.example.mydemo;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
public class MyDemo extends Activity {
private LinearLayout root;
private Button btnReset;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_demo);
root = (LinearLayout) findViewById(R.id.root);
btnReset = (Button) findViewById(R.id.reset);
final MyImageView view = new MyImageView(this);
view.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT));
root.addView(view);
btnReset.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
view.reset();
}
});
}
}
MyImageView.java
package com.example.mydemo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import java.util.ArrayList;
import java.util.List;
public class MyImageView extends ImageView implements View.OnTouchListener {
private int id = -1;
private Path path;
private List<Path> paths = new ArrayList<Path>();
private List<PointF> points = new ArrayList<PointF>();
boolean multiTouch = false;
public MyImageView(Context context) {
super(context);
this.setOnTouchListener(this);
}
public void reset() {
paths.clear();
points.clear();
path = null;
id = -1;
invalidate();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = createPen(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
for (Path path : paths) {
canvas.drawPath(path, paint);
}
for (int i = 0; i < points.size(); i++) {
PointF p = points.get(i);
canvas.drawText("" + p.x, p.y, i, createPen(Color.WHITE));
}
}
private PointF copy(PointF p) {
PointF copy = new PointF();
copy.set(p);
return copy;
}
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
multiTouch = false;
id = event.getPointerId(0);
PointF p = getPoint(event, id);
path = new Path();
path.moveTo(p.x, p.y);
paths.add(path);
points.add(copy(p));
break;
case MotionEvent.ACTION_POINTER_DOWN:
multiTouch = true;
for (int i = 0; i < event.getPointerCount(); i++) {
int tId = event.getPointerId(i);
if (tId != id) {
points.add(getPoint(event,i));
}
}
break;
case MotionEvent.ACTION_MOVE:
if (!multiTouch) {
p =getPoint(event, id);
path.lineTo(p.x, p.y);
}
break;
}
invalidate();
return true;
}
private PointF getPoint(MotionEvent event, int i) {
int index = 0;
return new PointF(event.getX(index), event.getY(index));
}
private Paint createPen(int color) {
Paint pen = new Paint();
pen.setColor(color);
float width = 3;
pen.setStrokeWidth(width);
return pen;
}
}
activity_my_demo.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="#+id/root" xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button android:id="#+id/reset" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Reset"
/>
</LinearLayout>
Can any one tell me what should be added or changed in my code so that I can use different colors for Chalk?
You can take the sample in your android folder's..
For the color picker go to in this folder:
android/samples/android-YOURS_VERSION/ApiDemos
Use this, review this code. than your problem will be solve
package com.example.changecolor;
import android.app.Activity;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends Activity
implements View.OnClickListener, UberColorPickerDialog.OnColorChangedListener {
private int mColor = 0xFFFF0000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Write the version number
PackageManager pm = getPackageManager();
String versionName = "";
try {
PackageInfo pi = pm.getPackageInfo("com.keithwiley.android.ubercolorpickerdemo", 0);
versionName = pi.versionName;
}
catch (Exception e) {
}
TextView textView = (TextView) findViewById(R.id.version);
textView.setText(versionName);
//Initialize the sample
((LinearLayout) findViewById(R.id.LinearLayout)).setBackgroundColor(mColor);
float hsv[] = new float[3];
Color.colorToHSV(mColor, hsv);
if (UberColorPickerDialog.isGray(mColor))
hsv[1] = 0;
if (hsv[2] < .5)
((TextView) findViewById(R.id.sample)).setTextColor(Color.WHITE);
else ((TextView) findViewById(R.id.sample)).setTextColor(Color.BLACK);
//Set up the buttons
Button button = (Button) findViewById(R.id.colorPickerWithTitle);
button.setOnClickListener(this);
button = (Button) findViewById(R.id.colorPickerWithToast);
button.setOnClickListener(this);
}
protected void onPause() {
super.onPause();
}
protected void onResume() {
super.onResume();
}
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
return true;
}
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
}
return super.onOptionsItemSelected(item);
}
public void onClick(View v) {
if (v.getId() == R.id.colorPickerWithTitle)
new UberColorPickerDialog(this, this, mColor, true).show();
if (v.getId() == R.id.colorPickerWithToast)
new UberColorPickerDialog(this, this, mColor, false).show();
}
public void colorChanged(int color) {
((LinearLayout) findViewById(R.id.LinearLayout)).setBackgroundColor(mColor=color);
float hsv[] = new float[3];
Color.colorToHSV(mColor, hsv);
//if (UberColorPickerDialog.isGray(mColor))
// hsv[1] = 0;
if (hsv[2] < .5)
((TextView) findViewById(R.id.sample)).setTextColor(Color.WHITE);
else ((TextView) findViewById(R.id.sample)).setTextColor(Color.BLACK);
}
}
And use the color picker class

Changing dragshadow in android, while dragging happens

Faced the problem of letting the dragshaddow (created by a DragShadowBuilder) react on something, while dragging is happening.
Do someone know how it supposed to be done?
Here's my complete code for custom drag shadow builder (gist for custom drag shadow).
However, as others stated there is no possibility to modify drag shadow using native functionality introduced in API-11.
package com.marcingil.dragshadow;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.view.View;
public class ImageDragShadowBuilder extends View.DragShadowBuilder {
private Drawable shadow;
private ImageDragShadowBuilder() {
super();
}
public static View.DragShadowBuilder fromResource(Context context, int drawableId) {
ImageDragShadowBuilder builder = new ImageDragShadowBuilder();
builder.shadow = context.getResources().getDrawable(drawableId);
if (builder.shadow == null) {
throw new NullPointerException("Drawable from id is null");
}
builder.shadow.setBounds(0, 0, builder.shadow.getMinimumWidth(), builder.shadow.getMinimumHeight());
return builder;
}
public static View.DragShadowBuilder fromBitmap(Context context, Bitmap bmp) {
if (bmp == null) {
throw new IllegalArgumentException("Bitmap cannot be null");
}
ImageDragShadowBuilder builder = new ImageDragShadowBuilder();
builder.shadow = new BitmapDrawable(context.getResources(), bmp);
builder.shadow.setBounds(0, 0, builder.shadow.getMinimumWidth(), builder.shadow.getMinimumHeight());
return builder;
}
#Override
public void onDrawShadow(Canvas canvas) {
shadow.draw(canvas);
}
#Override
public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
shadowSize.x = shadow.getMinimumWidth();
shadowSize.y = shadow.getMinimumHeight();
shadowTouchPoint.x = (int)(shadowSize.x / 2);
shadowTouchPoint.y = (int)(shadowSize.y / 2);
}
}

background scrolling with item in gridview

How do I implement background scrolling with a gridview? If it sounds vague, I mean like implementing a bookshelf using a gridview where the shelf image is attached to an item in the gridview.
It took me forever to figure this out, so for everybody trying to do this, here's the code from my e-book reader.
It's based on Shelves by Romain Guy so he deserves the credit for the original code.
package net.nightwhistler.pageturner.view;
import net.nightwhistler.pageturner.R;
import net.nightwhistler.pageturner.library.LibraryBook;
import net.nightwhistler.pageturner.library.QueryResult;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.widget.GridView;
public class BookCaseView extends GridView {
private Bitmap background;
private int mShelfWidth;
private int mShelfHeight;
private QueryResult<LibraryBook> result;
private LibraryBook selectedBook;
public BookCaseView(Context context, AttributeSet attributes) {
super(context, attributes);
this.setFocusableInTouchMode(true);
this.setClickable(false);
final Bitmap shelfBackground = BitmapFactory.decodeResource(context.getResources(),
R.drawable.shelf_single);
setBackground(shelfBackground);
this.setFocusable(true);
}
public void setBackground(Bitmap background) {
this.background = background;
mShelfWidth = background.getWidth();
mShelfHeight = background.getHeight();
}
protected void onClick( int bookIndex ) {
LibraryBook book = this.result.getItemAt(bookIndex);
this.selectedBook = book;
invalidate();
}
#Override
protected void dispatchDraw(Canvas canvas) {
final int count = getChildCount();
final int top = count > 0 ? getChildAt(0).getTop() : 0;
final int shelfWidth = mShelfWidth;
final int shelfHeight = mShelfHeight;
final int width = getWidth();
final int height = getHeight();
final Bitmap background = this.background;
for (int x = 0; x < width; x += shelfWidth) {
for (int y = top; y < height; y += shelfHeight) {
canvas.drawBitmap(background, x, y, null);
}
//This draws the top pixels of the shelf above the current one
Rect source = new Rect(0, mShelfHeight - top, mShelfWidth, mShelfHeight);
Rect dest = new Rect(x, 0, x + mShelfWidth, top );
canvas.drawBitmap(background, source, dest, null);
}
super.dispatchDraw(canvas);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ( keyCode == KeyEvent.KEYCODE_BACK && this.selectedBook != null ) {
this.selectedBook = null;
invalidate();
return true;
}
return false;
}
}
What I did was to split my background image in n gridview columns and in my gridview getView method add the view background according to the position in the grid.
It worked perfectly.
If you want the code just ask.
My previous answer only adds the background but doesn't let it scroll with the items. what you wan is NightWhistler's answer :)
Sorry for misinterpreting the question.

Categories

Resources