Friday, August 26, 2011

Gradients -- A deeper look


There is a setShader function within drawables. The following simplify coloring of a drawable object:

ShapeDrawable aDrawable = new ShapeDrawable(new OvalShape());
LinearGradient AGradient = new LinearGradient(x, y, x1, y1, LeftTopColor, RightbottomColor, Shader.TileMode.CLAMP);
aDrawable.getPaint().setShader(AGradient);

The result of simple manipulation on x, y, x1, y1



coding -
Butn 1 - new LinearGradient(0, 0, 50, 0, ColorYellow, ColorRed, Shader.TileMode.CLAMP);
Butn 2 - new LinearGradient(0, 0, 0, 50, ColorYellow, ColorRed, Shader.TileMode.CLAMP);
Butn 3 - new LinearGradient(50, 0, 0, 0, ColorYellow, ColorRed, Shader.TileMode.CLAMP);
Butn 4 - new LinearGradient(0, 50, 0, 0, ColorYellow, ColorRed, Shader.TileMode.CLAMP);




With the absence of either x or y, we have a gradient from x to y (Either top to bottom or right to left). With x and y (as below), we will have a gradient from top-left to bottom-right or top-right to bottom-left.

My belief is that x,y forms the coordinates for color1 and x1,y1 forms the coordinates for color2.
The distance between x1,y1 and x,y determines the direction of the gradient and angle.

shifting the numbers slightly
Butn 1 - new LinearGradient(0, 0, 50, 50, ColorYellow, ColorRed, Shader.TileMode.CLAMP);
Butn 2 - new LinearGradient(0, 0, 100, 100, ColorYellow, ColorRed, Shader.TileMode.CLAMP);
Butn 3 - new LinearGradient(50, 50, 0, 0,ColorYellow, ColorRed, Shader.TileMode.CLAMP);
Butn 4 - new LinearGradient(100, 100, 0, 0, ColorYellow, ColorRed, Shader.TileMode.CLAMP);

result:




Butn 1 - new LinearGradient(50, 50, 50, 0, ColorYellow, ColorRed, Shader.TileMode.CLAMP);
Butn 2 - new LinearGradient(0, 50, 50, 0, ColorYellow, ColorRed, Shader.TileMode.CLAMP);
Butn 3 - new LinearGradient(50, 0, 50, 0,ColorYellow, ColorRed, Shader.TileMode.CLAMP);
Butn 4 - new LinearGradient(0, 0,50, 0, ColorYellow, ColorRed, Shader.TileMode.CLAMP);


Saturday, August 20, 2011

State List Drawables

It takes a long time to figure this out by referring to documentation

The objective is to make a customizable button that reacts to user-touch input

In android, there are many states to a View in any particular time. State List Drawables can be used to control the appearance of the View in reaction to the particular state.

In this example i will have two buttons, each having a single statelistdrawable and a onClickListener that will change the other's state.


--------------------------- A statelistdrawable subclass --------------------------------

public class ImDraw extends StateListDrawable {
int alphaValue; int heightValue; int widthValue;
Canvas canvasIM;
ColorFilter cFilter;
StateListDrawable ImSLDrawable;
Drawable ImDrawable; Drawable ImDrawable1; Drawable ImDrawable2;
Paint paintIM;
int xHeight; int xWidth;
int currentType;
public ImDraw(int drawType, int intHeight, int intWidth){
//Set default values on start
alphaValue = 255;
cFilter = new ColorFilter();
currentType = drawType; xHeight = intHeight; xWidth = intWidth;
}
public StateListDrawable getSLD(){
//Set drawables colors
int drawColor1 = Color.argb(alphaValue, 255, 0, 0); //Paint Red
int drawColor2 = Color.argb(alphaValue, 255, 255, 0); //Paint Yellow
int drawColor3 = Color.argb(alphaValue, 255, 255, 255); //Paint White

//Draw desired drawables for the states - note the sub-class of normalSingleDrawables
normalSingleDrawables nSDA = new normalSingleDrawables(1, xHeight, xWidth, drawColor1, alphaValue);
normalSingleDrawables nSDB = new normalSingleDrawables(1, xHeight, xWidth, drawColor2, alphaValue);
normalSingleDrawables nSDC = new normalSingleDrawables(1, xHeight, xWidth, drawColor3, alphaValue);
ImSLDrawable = new StateListDrawable();
//Setup states to android.attr state
// int stateChecked = android.R.attr.state_checked;
int stateFocused = android.R.attr.state_focused;
int statePressed = android.R.attr.state_pressed;
int stateSelected = android.R.attr.state_selected;
//Set states --- notice 15 is setup as an additional, outside android.attr state
ImSLDrawable.addState(new int[] {15}, nSDC);
ImSLDrawable.addState(new int[] {statePressed}, nSDA);
ImSLDrawable.addState(new int[] {stateSelected}, nSDA);
ImSLDrawable.addState(new int[] {stateFocused}, nSDA);
ImSLDrawable.addState(new int[] {-stateFocused, -statePressed, -stateSelected}, nSDB);
return ImSLDrawable;

}
// ----- Start sub-class
class normalSingleDrawables extends Drawable{
int alphaValue;
int xPos = 1 ;int yPos = 1;
int xWidth; int yHeight;
int paintcolor;

public normalSingleDrawables(int choice, int intHeight, int intWidth, int dPaint, int alpha) {
xWidth = intWidth; yHeight = intHeight;
paintcolor = dPaint;
alphaValue = alpha;

//set the shape of drawable based on values

switch (choice) {
case 1: //Draw a rectangle
ImDrawable = new ShapeDrawable(new RectShape());
break;
case 2: //Draw a circle
ImDrawable = new ShapeDrawable(new OvalShape());
break;
default: //Draw a rectangle
ImDrawable = new ShapeDrawable(new RectShape());
} }

public void draw(Canvas canvasIM) {
((ShapeDrawable) ImDrawable).getPaint().setColor(paintcolor);
ImDrawable.setBounds(xPos, yPos, xPos + xWidth ,yPos + yHeight);
ImDrawable.draw(canvasIM); }

@Override
public int getOpacity() {
return PixelFormat.OPAQUE; }

@Override
public void setAlpha(int newAlphaValue) {
alphaValue = newAlphaValue; }

@Override
public void setColorFilter(ColorFilter cf) {
cf = cFilter; }
}

// ----- End sub-class
}

--------------------------- A statelistdrawable subclass --------------------------------
------------------------ On Application main activity --------------------------------
public class MYIM extends Activity {
//Default
TextView mainTextView;
String Msg = "";
Button mainButton = null; Button SideButton = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
//default activity code
super.onCreate(savedInstanceState);
//reference main.xml as User Interface
setContentView(R.layout.main);
//Set references point to our main.xml file - there must be two buttons with id -btnMain and btnSide
mainButton = (Button) findViewById(R.id.btnMain);
SideButton = (Button) findViewById(R.id.btnSide);
//Create our custom SLD
//Set drawables for our buttons
ImDraw NewIM = new ImDraw(1,
mainButton.getLayoutParams().height, mainButton.getLayoutParams().width);
mainButton.setBackgroundDrawable(NewIM.getSLD());

NewIM = new ImDraw(1,
SideButton.getLayoutParams().height, SideButton.getLayoutParams().width);
SideButton.setBackgroundDrawable(NewIM.getSLD());

//Set onClick for our buttons
mainButton.setOnClickListener(new OnClickListener(){
public void onClick(View view){
//Switch the other button to State No 15!
SideButton.getBackground().setState(new int[]{15});
}
});
SideButton.setOnClickListener(new OnClickListener(){
public void onClick(View view){
//Switch the other button to State No 15!
mainButton.getBackground().setState(new int[]{15});
}
});

}
}