In Android, I create an ImageView in the Java code and set its layout parameters: width, height and top margin before adding it to the main layout (RelativeLayout). The width and height are applied successfully, but the margin doesn't have any affect on the image view position. The actual top margin stays 0.
How to apply the top margin to views? The code is below.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initClouds();
}
private void initClouds() {
addCloud(R.drawable.cloud1, R.dimen.cloud1_top_margin);
addCloud(R.drawable.cloud2, R.dimen.cloud2_top_margin);
}
private void addCloud(int imageResId, int topMarginResId) {
RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.mainLayout);
ImageView cloud = new ImageView(this);
int height = (int) getResources().getDimension(R.dimen.cloud_height);
int width = (int) getResources().getDimension(R.dimen.cloud_width);
ViewGroup.MarginLayoutParams params = new ViewGroup.MarginLayoutParams(width, height);
params.topMargin = (int) getResources().getDimension(topMarginResId);
cloud.setImageResource(imageResId);
mainLayout.addView(cloud, params);
}
}
For setting the margin for a view inside RelativeLayout you should use RelativeLayout.LayoutParams . Change your code like this ,
private void addCloud(int imageResId, int topMarginResId) {
RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.mainLayout);
ImageView cloud = new ImageView(this);
int height = (int) getResources().getDimension(R.dimen.cloud_height);
int width = (int) getResources().getDimension(R.dimen.cloud_width);
RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(width, height);
param.topMargin = (int) getResources().getDimension(topMarginResId);
cloud.setImageResource(imageResId);
mainLayout.addView(cloud, param);
}
Related
Finally found a workaround: I decided to just use a table with a single row and then set stretchAllColumns to true. This means it just mimics a horizontal layout with spread-out views.
I am trying to instantiate a horizontal linear layout at runtime and I would like the elements in the layout to spread out along the full width of the layout. I would also like everything to be center-vertical aligned. This is currently what I've got:
LinearLayout tertiaryLinearLayout = new LinearLayout(getActivity());
tertiaryLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
tertiaryLinearLayout.setOrientation(LinearLayout.HORIZONTAL);
tertiaryLinearLayout.setGravity(Gravity.FILL_HORIZONTAL);
This instantiates the layout but the elements in it don't correctly fill the full width of it. I am also not sure how I can get them to be center-vertical aligned without changing setGravity to
tertiaryLinearLayout.setGravity(Gravity.CENTER_VERTICAL);
This TextView is one of the five elements I add to the layout:
TextView dash = new TextView(getActivity());
dash.setText("-");
Two of the elements are ImageViews and the other three are TextViews. Here is how it looks currently:
https://i.stack.imgur.com/MGLyJ.jpg
EDIT:
The overall structure is a ScollView with a vertical LinearLayout. This LinearLayout holds lots of other vertical LinearLayouts, each with a horizontal LinearLayout. Hope that makes sense.
The parent view of tertiaryLinearLayout is here:
LinearLayout secondaryLinearLayout = new LinearLayout(getActivity());
secondaryLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
secondaryLinearLayout.setOrientation(LinearLayout.VERTICAL);
...
secondaryLinearLayout.addView(tertiaryLinearLayout);
EDIT 2:
Here is my full code:
...
final LinearLayout linearLayout = root.findViewById(R.id.leagueLinearLayout);
List<Game> currentYearCategory = MainActivity.yearCategories.get(0);
for (int i = 0; i < currentYearCategory.size(); i++) {
TextView textView = new TextView(getActivity());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
textView.setLayoutParams(params);
textView.setText(currentYearCategory.get(i).date);
linearLayout.addView(textView);
}
seekBarChange(linearLayout, root, 0);
// Set up seek bar
SeekBar yearSeekBar = root.findViewById(R.id.yearSeekBar);
yearSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
seekBarChange(linearLayout, root, progress);
}
...
...
private void seekBarChange(LinearLayout linearLayout, View root, int progress){
TextView yearTextView = root.findViewById(R.id.yearTextView);
String newText = (1890 + progress * 10) + " - " + (1899 + progress * 10);
yearTextView.setText(newText);
final List<Game> currentYearCategory = MainActivity.yearCategories.get(progress);
linearLayout.removeAllViews();
for (int i = 0; i < currentYearCategory.size(); i++) {
// Create views
LinearLayout secondaryLinearLayout = new LinearLayout(getActivity());
secondaryLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
secondaryLinearLayout.setOrientation(LinearLayout.VERTICAL);
View separatorView = new View(getActivity());
separatorView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 50));
TextView date = new TextView(getActivity());
date.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
date.setText(currentYearCategory.get(i).date);
LinearLayout tertiaryLinearLayout = new LinearLayout(getActivity());
tertiaryLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
tertiaryLinearLayout.setOrientation(LinearLayout.HORIZONTAL);
tertiaryLinearLayout.setGravity(Gravity.CENTER_VERTICAL);
ImageView homeImage = new ImageView(getActivity());
homeImage.setLayoutParams(new ViewGroup.LayoutParams(150, 150));
if (currentYearCategory.get(i).celticIsHome){
homeImage.setBackgroundResource(R.drawable.celtic_logo);
} else {
homeImage.setBackgroundResource(R.drawable.rangers_logo);
}
TextView homeScore = new TextView(getActivity());
homeScore.setText(currentYearCategory.get(i).fullTimeScore.substring(0, 1));
TextView dash = new TextView(getActivity());
dash.setText("-");
TextView awayScore = new TextView(getActivity());
awayScore.setText(currentYearCategory.get(i).fullTimeScore.substring(2));
ImageView awayImage = new ImageView(getActivity());
awayImage.setLayoutParams(new ViewGroup.LayoutParams(150, 150));
if (currentYearCategory.get(i).celticIsHome){
awayImage.setBackgroundResource(R.drawable.rangers_logo);
} else {
awayImage.setBackgroundResource(R.drawable.celtic_logo);
}
// Add views
tertiaryLinearLayout.addView(homeImage);
tertiaryLinearLayout.addView(homeScore);
tertiaryLinearLayout.addView(dash);
tertiaryLinearLayout.addView(awayScore);
tertiaryLinearLayout.addView(awayImage);
secondaryLinearLayout.addView(separatorView);
secondaryLinearLayout.addView(date);
secondaryLinearLayout.addView(tertiaryLinearLayout);
final int gameNum = i;
secondaryLinearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openGameActivity(currentYearCategory, gameNum);
}
});
linearLayout.addView(secondaryLinearLayout);
}
}
Any help would be greatly appreciated, thanks!
I guess that the PARENT view that the tertiaryLinearLayout will be added to is wrap_content for the layout_width. Try to make its width match_parent. You should have a look on this tutorial at 2:52s
I am trying to clean my java code by placing RelativeLayout.LayoutParams inside a function, so that I don't have to create new layoutparams everytime I add new thing.
The problem: I got an error code
Unable to start activity ComponentInfo{onedevz.com.noct/onedevz.com.noct.MainActivity}: java.lang.NullPointerException: Layout parameters cannot be null
it says I got no layout param even though I do have one and I called it before I placed it into a Button. here is the code
public class MainActivity extends AppCompatActivity {
MicButton micbutton;
Button menuBtn,onBtn;
EditText text;
RelativeLayout relativeLayout;
RelativeLayout.LayoutParams lp1,lp2,lp3,lp4;
boolean clicked;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Creating a new RelativeLayout
relativeLayout = new RelativeLayout(this);
// Defining the RelativeLayout layout parameters.
// In this case I want to fill its parent
RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.FILL_PARENT);
// Defining the layout parameters of the TextView
placement(lp1,100,100,0,200,40,0,RelativeLayout.ALIGN_PARENT_BOTTOM,RelativeLayout.ALIGN_PARENT_LEFT);
placement(lp2,100,100,0,350,40,0,RelativeLayout.ALIGN_PARENT_BOTTOM,RelativeLayout.ALIGN_PARENT_LEFT);
placement(lp3,100,100,0,500,40,0,RelativeLayout.ALIGN_PARENT_BOTTOM,RelativeLayout.ALIGN_PARENT_LEFT);
placement(lp4,100,ViewGroup.MarginLayoutParams.MATCH_PARENT,150,0,40,0,RelativeLayout.ALIGN_PARENT_TOP,RelativeLayout.CENTER_HORIZONTAL);
setParameter();
addView();
// Setting the RelativeLayout as our content view
setContentView(relativeLayout, rlp);
}
void placement(RelativeLayout.LayoutParams name,int height,int width,int topMargin,int bottomMargin,int leftMargin,int rightMargin,int rule1,int rule2){
name = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
name.addRule(rule1);
name.addRule(rule2);
name.leftMargin = leftMargin;
name.bottomMargin = bottomMargin;
name.height = height;
name.width = width;
}
void setParameter(){
// Setting the parameters on the TextView
micbutton.setLayoutParams(lp1);
onBtn.setLayoutParams(lp2);
menuBtn.setLayoutParams(lp3);
text.setLayoutParams(lp4);
}
void addView(){
// Adding the TextView to the RelativeLayout as a child
relativeLayout.addView(micbutton);
relativeLayout.addView(text);
}
}
Any help will be appreciated, Thanks.
Your LayoutParameters lp1,lp2,lp3,lp4 have not been initialized. Initialize them and then set it to the TextView.
Solution:
Write like this:
void placement(RelativeLayout.LayoutParams name,int height,int width,int topMargin,int bottomMargin,int leftMargin,int rightMargin,int rule1,int rule2){
name = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
name.addRule(rule1);
name.addRule(rule2);
name.leftMargin = leftMargin;
name.bottomMargin = bottomMargin;
name.height = height;
name.width = width;
void setParameter();
}
void setParameter(){
// Setting the parameters on the TextView
micbutton.setLayoutParams(lp1);
onBtn.setLayoutParams(lp2);
menuBtn.setLayoutParams(lp3);
text.setLayoutParams(lp4);
void addView();
}
void addView(){
// Adding the TextView to the RelativeLayout as a child
relativeLayout.addView(micbutton);
relativeLayout.addView(text);
}
Hopefully it should solve your issue.
This seems to be easy to state but there seems no straight forward implementation. I want to limit the movement of an imageview to its direct parent. I couldn't find examples related to this. Can somebody help me with an example for this?
I actually want to achieve a motion where the leaf in middle is moved, the leaf at the top should move to bottom and the bottom leaf should move to the middle and the middle leaf should move to top position. This coupled with the elevation of the middle leaf. Please refer to the image below.
I have tried to achieve this by using the rect of the parent view in onTouch of the view but that doesn't seem to work. Tried to achieve this listview and recyclerview but that seems to add a lot of complexity to a simple requirement.
Here is my code
public class Main6Activity extends AppCompatActivity {
ImageView imageView;
private int _xDelta;
private int _yDelta;
View view;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main6);
imageView = (ImageView)findViewById(R.id.img1);
view = findViewById(R.id.imglayout);
final Rect rect = new Rect(view.getLeft(),view.getTop(),view.getRight(),view.getBottom());
imageView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
if(event.getAction() == MotionEvent.ACTION_DOWN){
LinearLayout.LayoutParams lParams = (LinearLayout.LayoutParams) imageView.getLayoutParams();
_xDelta = X - lParams.leftMargin;
_yDelta = Y - lParams.topMargin;
}
if (event.getAction() == MotionEvent.ACTION_MOVE){
if(isViewContains(X,Y)){
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) imageView.getLayoutParams();
layoutParams.leftMargin = X - _xDelta;
layoutParams.topMargin = Y - _yDelta;
layoutParams.rightMargin = -250;
layoutParams.bottomMargin = -250;
imageView.setLayoutParams(layoutParams);
}
}
return true;
}
});
}
private boolean isViewContains(int rx,int ry) {
int[] l = new int[2];
view.getLocationOnScreen(l);
Rect rect1 = new Rect(l[0], l[1], l[0] + view.getWidth(), l[1] + imageView.getHeight());
return rect1.contains(rx, ry);
}
}
I don't use xml in my UI.
My code of mainlayout:
public class MainActivity extends ActionBarActivity {
LinearLayout LinLay;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ScrollView sv = new ScrollView(this);
this.setContentView(sv);
LinLay = new LinearLayout(this);
LinLay.setOrientation(LinearLayout.VERTICAL);
LinLay.setBackgroundColor(Color.parseColor("#000000"));
sv.addView(LinLay);
And adding a Edittext:
EditText txt = new EditText(this);
txt.setBackgroundColor(Color.parseColor("#ff9a16"));
txt.setHint("Txt(0,0)");
LayoutParams txtParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
txtParams.width = 300;
txtParams.height = 70;
txtParams.leftMargin = 0;
txtParams.topMargin = 0;
txt.setLayoutParams(txtParams);
LinLay.addView(txt);
Finally adding a Button:
Button btn = new Button(this);
btn.setBackgroundColor(Color.parseColor("#cb0016"));
btn.setText("Btn(0,0)");
LayoutParams btnParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
btnParams.width = 300;
btnParams.height = 70;
btnParams.leftMargin = 0;
btnParams.topMargin = 0;
btn.setLayoutParams(btnParams);
LinLay.addView(btn); }
The Edittext's must be X position = 0 and Y position = 0 of MainScreen.
The Button's must be X position = 0 and Y position = 0 of MainScreen.
But the Button taking referance is the Edittext and it takes position in X:0,Y:70 of MainScreen.
The program screen: prntscr.com/4ixo7z
If my LinearLayout that's LinLay is Horizontal, the button takes position in X:300,Y:0 of MyScreen. I want to taking position in MainScreen. I don't want to taking referance. Help me.
The Horizontal screen: prntscr.com/4ixo8i
Change your LinearLayout and use RelativeLayout, remove orientation. add your product relatively, this will solve your issue.
Hi I've been having problems with my code with null pointer exceptions (see my other questions) so I've gone for creating my view dynamically.
Here's my code:
public class HarvestLifeActivity extends Activity implements OnTouchListener {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//add touch listeners for buttons : assign each a name and link it.
View MoveUp = findViewById(R.id.up);
MoveUp.setOnTouchListener(this); // use (this) to link to the current onTouchListener references in class declaration above.
View MoveDown = findViewById(R.id.down);
MoveDown.setOnTouchListener(this);
View MoveLeft = findViewById(R.id.left);
MoveLeft.setOnTouchListener(this);
View MoveRight = findViewById(R.id.right);
MoveRight.setOnTouchListener(this);
}
#Override
protected void onStart() {
super.onStart();
Drawable standing = getResources().getDrawable(R.drawable.test_circle);
//code to convert character size from pixel to dp
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
float logicalDensity = metrics.density;
int pxToConv = 50;
int convToDp = (int) (pxToConv / logicalDensity + 0.5);
RelativeLayout characterContainer = new RelativeLayout(this);
RelativeLayout.LayoutParams characParams = new RelativeLayout.LayoutParams(convToDp, convToDp);
characParams.addRule(RelativeLayout.CENTER_IN_PARENT);
characterContainer.setBackgroundDrawable(standing);
characterContainer.setId(101);
}
// Process button clicks
public boolean onTouch(View v, MotionEvent event) {
switch(v.getId()){
case R.id.up:
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//as long as up button is pressed it will keep moving character up
while (event.getAction() == MotionEvent.ACTION_DOWN)
{
RelativeLayout characterContainer = (RelativeLayout) findViewById(101);
Drawable walking = getResources().getDrawable(R.drawable.test_circle_red);
int startX = characterContainer.getLeft();
int startY = characterContainer.getTop();
int defaultWidth = characterContainer.getWidth();
int defaultHeight = characterContainer.getHeight();
//create new position for character 1 pixel closer to the top of screen
int newX = startX - 1;
int newY = startY;
//remove character
RelativeLayout view = (RelativeLayout) characterContainer;
ViewGroup owner = (ViewGroup) view.getParent();
owner.removeView(view);
//re make character in new position created above and assign background as walking forwards animation
RelativeLayout.LayoutParams characParams = new RelativeLayout.LayoutParams(defaultWidth,defaultHeight);
characParams.leftMargin = newY;
characParams.topMargin = newX;
characterContainer.setLayoutParams(characParams);
characterContainer.setBackgroundDrawable(walking);
}
break;
// when button is let go of
case MotionEvent.ACTION_UP:
RelativeLayout characterContainer = (RelativeLayout) findViewById(101);
Drawable standing = getResources().getDrawable(R.drawable.test_circle);
characterContainer.setBackgroundDrawable(standing);
default:
break;
}
return true;
case R.id.down:
.. ..
}
return true;
}
}
When I run it the created layout is not there.
Is there something I've missed?
You are creating a RelativeLayout object, but never setting it as the content for the window...
make your onCreate Look like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Cut these lines out of onStart();
RelativeLayout characterContainer = new RelativeLayout(this);
RelativeLayout.LayoutParams characParams = new RelativeLayout.LayoutParams(convToDp, convToDp);
characParams.addRule(RelativeLayout.CENTER_IN_PARENT);
characterContainer.setBackgroundDrawable(standing);
characterContainer.setId(101);
setContentView(characterContainer);
//add touch listeners for buttons : assign each a name and link it.
/*View MoveUp = findViewById(R.id.up);
MoveUp.setOnTouchListener(this); // use (this) to link to the current onTouchListener references in class declaration above.
View MoveDown = findViewById(R.id.down);
MoveDown.setOnTouchListener(this);
View MoveLeft = findViewById(R.id.left);
MoveLeft.setOnTouchListener(this);
View MoveRight = findViewById(R.id.right);
MoveRight.setOnTouchListener(this);*/
}
you are not adding your created layout to the existing view.
thats your problem.
addview(your_layout);