title: In Android, how do I set margins in dp programmatically?
body: <p>In <a href="https://stackoverflow.com/questions/2481455/set-margins-in-a-linearlayout-programmatically">this</a>, <a href="https://stackoverflow.com/questions/7981456/setting-buttons-margin-programmatically">this</a> and <a href="https://stackoverflow.com/questions/8312215/adding-margins-to-button-object-programatically">this</a> thread I tried to find an answer on how to set the margins on a single view. However, I was wondering if there isn't an easier way. I'll explain why I rather wouldn't want to use this approach:</p>
  
  <p>I have a custom Button which extends Button. If the background is set to something else than the default background (by calling either <code>setBackgroundResource(int id)</code> or <code>setBackgroundDrawable(Drawable d)</code>), I want the margins to be 0. If I call this:</p>
  
  <pre><code>public void setBackgroundToDefault() {
      backgroundIsDefault = true;
      super.setBackgroundResource(android.R.drawable.btn_default);
      // Set margins somehow
  }
  </code></pre>
  
  <p>I want the margins to reset to -3dp (I already read <a href="https://stackoverflow.com/questions/4914039/margins-of-a-linearlayout-programmatically-with-dp">here</a> how to convert from pixels to dp, so once I know how to set margins in px, I can manage the conversion myself). But since this is called in the <code>CustomButton</code> class, the parent can vary from LinearLayout to TableLayout, and I'd rather not have him get his parent and check the instanceof that parent. That'll also be quite inperformant, I imagine.</p>
  
  <p>Also, when calling (using LayoutParams) <code>parentLayout.addView(myCustomButton, newParams)</code>, I don't know if this adds it to the correct position (haven't tried however), say the middle button of a row of five.</p>
  
  <p>Question: Is there any easier way to set the margin of a single Button programmatically <strong>besides using LayoutParams?</strong></p>
  
  <p>EDIT: I know of the LayoutParams way, but I'd like a solution that avoids handling each different container type:</p>
  
  <pre><code>ViewGroup.LayoutParams p = this.getLayoutParams();
      if (p instanceof LinearLayout.LayoutParams) {
          LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)p;
          if (_default) lp.setMargins(mc.oml, mc.omt, mc.omr, mc.omb);
          else lp.setMargins(mc.ml, mc.mt, mc.mr, mc.mb);
          this.setLayoutParams(lp);
      }
      else if (p instanceof RelativeLayout.LayoutParams) {
          RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)p;
          if (_default) lp.setMargins(mc.oml, mc.omt, mc.omr, mc.omb);
          else lp.setMargins(mc.ml, mc.mt, mc.mr, mc.mb);
          this.setLayoutParams(lp);
      }
      else if (p instanceof TableRow.LayoutParams) {
          TableRow.LayoutParams lp = (TableRow.LayoutParams)p;
          if (_default) lp.setMargins(mc.oml, mc.omt, mc.omr, mc.omb);
          else lp.setMargins(mc.ml, mc.mt, mc.mr, mc.mb);
          this.setLayoutParams(lp);
      }
  }
  </code></pre>
  
  <p>Because <code>this.getLayoutParams();</code>returns a <code>ViewGroup.LayoutParams</code>, which do not have the attributes <code>topMargin</code>, <code>bottomMargin</code>, <code>leftMargin</code>, <code>rightMargin</code>.
  The mc instance you see is just a <code>MarginContainer</code> which contains offset (-3dp) margins and (oml, omr, omt, omb) and the original margins (ml, mr, mt, mb).</p>