I am trying to set the background of a Button to a PaintDrawable which I am creating in code. This works pretty well, but my Button appears larger than an android.view.Button.
In the below image, the first Button is an instance of MyButton, the second button is an instance of android.widget.Button.
I tried both setting the padding on the PaintDrawable and MyButton, but neither has any noticeable effect.
public class MyButton extends Button
{
PaintDrawable drawable = null;
public ColorButton(Context context)
{
super(context);
drawable = new PaintDrawable();
drawable.getPaint().setColor(Color.WHITE);
drawable.setCornerRadius(1);
//neither of these seem to do anything?
drawable.setPadding(10, 10, 10, 10);
setPadding(10, 10, 10, 10);
setBackgroundDrawable(drawable);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//set gradient in here, because getWidth/getHeight are useless prior to this
drawable.getPaint().setShader(new LinearGradient(getMeasuredWidth()/2, 0, getMeasuredWidth()/2, getMeasuredHeight(), Color.WHITE, Color.GRAY, Shader.TileMode.MIRROR));
}
}
Please note the difference between padding and margins
Padding determines how much "padding" is on the inside of your container.
Margins determine how much space to leave around the outside of your container.
Since you are setting the padding on an empty container you should see no visible results.
If you had something inside your container you may notice it getting squished as you increase your values
Try this in your code. It will only work on the button (your parent class)
//set your fill values to whatever you want
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(10, 10, 10, 10);
setLayoutParams(lp);
Related
I have a table of buttons and am attempting to dynamically create and set the padding around the text of each with the following function:
public static void AddChartColBtn(TableRow row, String txt, String style) {
Button note_chart_btn;
note_chart_btn = new Button(ctx);
note_chart_btn.setText(txt);
TableRow.LayoutParams params = new TableRow.LayoutParams();
params.setMargins(0, 0, 0, 0);
note_chart_btn.setLayoutParams(params);
row.addView(note_chart_btn);
}
I've tried working with LayoutParams classes to set margins and paddings, etc...but no matter what I try the button always fills the entire space of the current table cell, ignoring any padding. The Button class doesn't appear to have layout params, padding that can be manipulated directly. How can dynamically create and declare a button with 0 padding around it's text?
set Both
params.setMargins(0, 0, 0, 0);
params.setPadding(0, 0, 0, 0);
Use like this.
Button note_chart_btn;
note_chart_btn = new Button(ctx);
note_chart_btn.setText(txt);
note_chart_btn.setGravity(Gravity.CENTER);
note_chart_btn.setPadding(left, top, right, bottom);
I hope this will help you.
Try setting something like this
android:padding="10dp" for every button you have in your layout in the .xml file of your layout
setPadding should after the setBackgroundResource
Like this:
button.setBackgroundResource(R.mipmap.btn_bg)
button.setPadding(100, 0, 100, paddingBo0tom)
I have the following in a class ProgressIndicatorView. The view, when used holds the five rectangles below :
When the user presses the button "Fortsæt" I call the views method setProgressIndicator(int step) which sets the color of the next rectangle in the view to fully opaque. The method looks like this :
public void setProgressIndicator(int activeStep) {
// Fade IN
TransitionDrawable transition = (TransitionDrawable) this.getChildAt(activeStep-1).getBackground();
transition.startTransition(transitionTime);
}
and the init method looks like this
private void init(Context context) {
this.setOrientation(LinearLayout.HORIZONTAL);
transitionColor = getResources().getDrawable(R.drawable.colortransition);
for (int i = 0; i < squareAmount; i++) {
ImageView loadingPiece = new ImageView(context);
//loadingPiece.setBackgroundColor(transparentWhite);
loadingPiece.setBackgroundDrawable(transitionColor);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(0,
LinearLayout.LayoutParams.FILL_PARENT, 1.0f);
lp.setMargins(0, 15, 4, 15);
this.addView(loadingPiece, lp);
}
}
The method works perfectly if I use a static backgroundcolor as the resource but doesn't when I use the transitioncolor drawable. Any suggestions as to what could be causing the issue ?
edit: for clarification THIS is what the view looks like when I use this.getChildAt(activeStep-1).setBackgroundColor(opaqueWhite);
but THIS is what it looks like when I use the current implementation of setProgressIndicator:
What is causing this to happen?
edit: Is there another approach that I could possibly to accomplish this effect if the cause of this problem cannot be located?
I have a class to which I need to add one or more Views. In this example, a single ImageView.
I can add views without a problem and align them using LayoutParameters, but when I try to align or center them somewhere along the vertical axis, they either stick to the top or don't appear at all (they are likely just out of view).
In the constructor I call a method fillView(), which happens after all dimensions and such are set.
fillView()
public void fillView(){
img = new ImageView(context);
rl = new RelativeLayout(context);
img.setImageResource(R.drawable.device_access_not_secure);
rl.addView(img, setCenter());
this.addView(rl, matchParent());
}
matchParent()
public LayoutParams matchParent(){
lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
lp.setMargins(0, 0, 0, 0);
return lp;
}
setCenter()
public LayoutParams setCenter(){
lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE); //This puts the view horizontally at the center, but vertically at the top
return lp;
}
Similarly, adding rules such as ALIGN_RIGHT or BELOW will work fine, but ALIGN_BOTTOM or CENTER_VERTICALLY will not.
I tried using both this method and the setGravity() a LinearLayout offers, with the same results.
You're adding your ImageView before you've added the RelativeLayout
While I still don't know why my method worked horizontally, but not vertically, I did solve the problem. The posted methods worked, the problem was hidden in onMeasure().
I previously set the dimensions by simply passing them to setMeasuredDimension(). I fixed the issue by also passing them to the layoutParams(). I also changed the integers I used to MeasureSpecs while I was at it.
I changed this:
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(this.getT_Width(), this.getT_Heigth());
this.setMeasuredDimension(desiredHSpec, desiredWSpec);
}
to this:
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
final int desiredHSpec = MeasureSpec.makeMeasureSpec(this.getT_heigth(), MeasureSpec.EXACTLY);
final int desiredWSpec = MeasureSpec.makeMeasureSpec(this.getT_width(), MeasureSpec.EXACTLY);
this.getLayoutParams().height = this.getT_heigth();
this.getLayoutParams().width = this.getT_width();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(desiredWSpec);
int height = MeasureSpec.getSize(desiredHSpec);
setMeasuredDimension(width, height);
}
getT_Width() and getT_Heigth() are methods I used to get some custom dimensions I set elsewhere.
I hope this helps somebody.
So I have a setup where I'm creating my own View and I'm adding some TextViews into it. However, the gravity setting is broken for it. (It centers horizontally, but not vertically) I'm doing it this way because there's other stuff I'm also drawing within my view besides just the TextViews, but those work fine. There's only a problem with the TextView gravity. Here's partial code of what I have.
public class myView extends View {
protected RelativeLayout baseLayout;
protected TextView textView1;
protected TextView textView2;
public myView (Context context) {
super(context);
setLayoutParams(new LayoutParams(FILL_PARENT, FILL_PARENT));
baseLayout = new RelativeLayout(context);
baseLayout.setLayoutParams(new LayoutParams(FILL_PARENT, FILL_PARENT));
textView1 = new TextView(context);
// initialize textView1 string, id, textsize, and color here
textView2 = new TextView(context);
// initialize textView2 string, id, textsize, and color here
baseLayout.addView(textView1);
baseLayout.addView(textView2);
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
Resources res = getResources();
// calculate out size and position of both textViews here
textView1.layout(left1, top1, left1 + width1, top1 + height1);
textView1.setGravity(Gravity.CENTER);
textView1.setBackgroundColor(green); // just to make sure it's drawn in the right spot
textView2.layout(left2, top2, left2 + width2, top2 + height2);
textView2.setGravity(Gravity.CENTER);
textView2.setBackgroundColor(blue); // same as above
baseLayout.draw(canvas);
}
}
This draws the TextViews in the exact spots and sizes that I want them (I know because of the background color), but the gravity sets them to be only centered horizontally.. not vertically. (yes, the TextViews are larger than the actual text strings)
I could PROBABLY implement the solution found here (TextView gravity), but that doesn't seem like a very efficient or reliable way to get around this. Is there something I'm doing wrong that's causing gravity to stop working correctly? Any input/help is appreciated.
Ok.. So I figured this out. I just had to run the measure() method on each TextView.. So my new code looks like:
textView1.measure(MeasureSpec.makeMeasureSpec(width1, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height1, MeasureSpec.EXACTLY));
textView1.layout(left1, top1, left1 + width1, top1 + height1);
textView1.setGravity(Gravity.CENTER);
textView2.measure(MeasureSpec.makeMeasureSpec(width2, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height2, MeasureSpec.EXACTLY));
textView2.layout(left2, top2, left2 + width2, top2 + height2);
textView2.setGravity(Gravity.CENTER);
Now it centers both horizontally and vertically like it should. If you're having the same issues, try this out.
You can set multiple Gravity parameters using setGravity like this.
textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL );
Hava a look on How do I center text horizontally and vertical in a TextView in Android?
I just ran into this problem, too. My issue was that when I set gravity on TextView by calling TextView.setGravity(), it silently affects the layout of itself(Textview) in parent view.
Here's what I did for the workaround fix:
TextView schedule = getBubbleTextView (item, hasZeroSpanEvent);
// There's a bug in TextView, we need to use wrapper to fix it
LinearLayout wrapper = new LinearLayout (getApplicationContext ());
wrapper.addView (schedule);
hourlyBubbleParent.addView (wrapper, llp);
You should grab the idea that you should use wrapper to workaround this.
I have a form with several Views on it, the last one is a Spinner that is bound to an adapter to get it's data from a Web Server via a POST request, at the end I append an additional entry for "Other...". If this option is selected on the spinner, a new EditText View at the bottom where the user enters a custom value, I've managed to get the EditText View to show on the screen, but it's positioned at the very top, over my other Views and I can't seem to find the way to make it appear at the bottom, below the Spinner as I want it to, here is the code I have so far:
EditText suggestCarrierField = new EditText(getBaseContext());
suggestCarrierField.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
suggestCarrierField.setHint("Suggest your carrier");
((AbsoluteLayout) findViewById(R.id.createAccountView)).addView(suggestCarrierField);
((AbsoluteLayout) findViewById(R.id.createAccountView)).invalidate();
Using an AbsoluteLayout, you need to use AbsoluteLayout.LayoutParams, rather than ViewGroup.LayoutParams.
int width = 100, height = 25, x = 0, y = 200;
AbsoluteLayout.LayoutParams lp = new AbsoluteLayout.LayoutParams(width, height, x, y);
suggestCarrierField.setLayoutParams(lp);
Having said that, I strongly urge you to consider implementing this with a RelativeLayout (or LinearLayout) instead... AbsoluteLayout is deprecated, and for very good reason. There are so many different Android devices with different sized screens now, AbsoluteLayout just won't work across them all.
When setting the LayoutParams for suggestCarrierField, don't use ViewGroup but instead use AbsoluteLayout.LayoutParams. It has a constructor which takes a height, width AND x and y coordinates. See the AbsoluteLayout.LayoutParams doc . Here is a quick app I whipped which demos this:
public class AbsoluteLayoutTest extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AbsoluteLayout as = new AbsoluteLayout(this);
TextView tvTop = new TextView(this);
tvTop.setText("top");
tvTop.setLayoutParams(new AbsoluteLayout.LayoutParams(AbsoluteLayout.LayoutParams.FILL_PARENT, AbsoluteLayout.LayoutParams.WRAP_CONTENT, 0, 0));
TextView tvMid = new TextView(this);
tvMid.setText("middle");
tvMid.setLayoutParams(new AbsoluteLayout.LayoutParams(AbsoluteLayout.LayoutParams.FILL_PARENT, AbsoluteLayout.LayoutParams.WRAP_CONTENT, 0, 80));
TextView tvBot = new TextView(this);
tvBot.setText("bottom");
tvBot.setLayoutParams(new AbsoluteLayout.LayoutParams(AbsoluteLayout.LayoutParams.FILL_PARENT, AbsoluteLayout.LayoutParams.WRAP_CONTENT, 0, 180));
as.addView(tvTop);
as.addView(tvMid);
as.addView(tvBot);
setContentView(as);
}
}
This will result in three text views. One at the top (y-coord = 0), one in the middle (y-coord = 80) and one at the bottom (y-coord = 180).