Problem with LayoutParam inside a function - java

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.

Related

Setting margin on view in RelativeLayout programmatically doesn't have any affect

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);
}

Android: how to listen dynamically added button's click?

I have the following code that upon image capture, places a RelativeLayout container, which contains ImageView of the image and Button that is supposed to be the X (Remove) button.
private void addImage(Bitmap photo) {
RelativeLayout rLayout = new RelativeLayout(getApplicationContext()); // Any difference between 'this' and 'getApplicationContext()'?
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParas(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
rLayout.setLayoutParams(params);
ImageView imageView = new ImageView(getApplicationContext());
imageView.setLayoutParams(new LayoutParams(100, 100));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setImageBitmap(photo);
RelativeLayout.LayoutParams bParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
bParams.addRule(RelativeLayout.ALIGN_RIGHT, imageView.getId());
bParams.addRule(RelativeLayout.ALIGN_TOP, imageView.getId());
bParams.setMargins(0, -10, -10, 0);
Button closeButton = new Button(getApplicationContext());
closeButton.setText("X"); // This will be an icon later
closeButton.setBackgroundColor(Color.RED); // For visualization purposes
closeButton.setLayoutParams(bParams);
rLayout.addView(imageView);
rLayout.addView(closeButton);
parentLinearLayout = (LinearLayout) findViewById(R.id.horizontal_scrolling_linear_layout);
parentLinearLayout.addView(rLayout);
}
The ideal scenario is having a close/delete button on top-right corner of the image, that upon click will remove the parent RelativeLayout from it's parent. Some styling and placements in the code might not make sense, I am JUST starting Android Development so any help will be appreciated. I am also including small questions in comments that would help me clear things up in Android Dev.
Question is: How can I capture button (X) click and remove the parent relative layout from the code?
Any help is appreciated, thank you!
Try this:
closeButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
((ViewGroup) rLayout.getParent()).removeView(rLayout);
}
});
I'd start by moving the following line into your Activity's onCreate():
parentLinearLayout = (LinearLayout) findViewById(R.id.horizontal_scrolling_linear_layout);
This helps to reduce unnecessary reassignment as well as clutter. Once that's done, the following should suit your needs.
Button closeButton = new Button(getApplicationContext());
closeButton.setText("X"); // This will be an icon later
closeButton.setBackgroundColor(Color.RED); // For visualization purposes
closeButton.setLayoutParams(bParams);
closeButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if (parentLinearLayout != null) {
parentLinearLayout.removeView(rLayout);
}
}
});
Just use
closeButton.setOnClickListener(new OnClickListener(){
//override method
public void onClick(View v) {
//do something
}
});
In addition,you can't remove the parent RelativeLayout ,because any view must be included by viewGroup.
And the difference between "this" and "getApplicationContext()" as you mentioned at the beginning is:
this == yourActivity.this ,it is activity's instance. However,getApplicationContext() will get Application's instance.
// Try this way,hope this will help you to solve your problem...
private void addImage(Bitmap photo) {
RelativeLayout rLayout = new RelativeLayout(getApplicationContext());
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
rLayout.setLayoutParams(params);
ImageView imageView = new ImageView(getApplicationContext());
imageView.setLayoutParams(new ViewGroup.LayoutParams(100, 100));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setImageBitmap(photo);
RelativeLayout.LayoutParams bParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
bParams.addRule(RelativeLayout.ALIGN_RIGHT, imageView.getId());
bParams.addRule(RelativeLayout.ALIGN_TOP, imageView.getId());
bParams.setMargins(0, -10, -10, 0);
Button closeButton = new Button(getApplicationContext());
closeButton.setText("X"); // This will be an icon later
closeButton.setBackgroundColor(Color.RED); // For visualization purposes
closeButton.setLayoutParams(bParams);
closeButton.setTag(0,parentLinearLayout);
closeButton.setTag(1,rLayout);
closeButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
LinearLayout parentLinearLayout = (LinearLayout)view.getTag(0);
RelativeLayout rLayout = (RelativeLayout)view.getTag(1);
parentLinearLayout.removeView(rLayout);
}
});
rLayout.addView(imageView);
rLayout.addView(closeButton);
parentLinearLayout = (LinearLayout) findViewById(R.id.horizontal_scrolling_linear_layout);
parentLinearLayout.addView(rLayout);
}

How to programatically make RelativeLayout that works

I have a problem with creating a working Layout in View class that will not crush the program. I think everything is done correctly in the code, but probably there are some setting I don't know about I hope that You guys will reveal that to me.
I am trying to do drawing View with a "Clear" button and RadioGroup.
So first od all, that works fine, but both added content Views (btnReset = "Clear", btnScale = RadioGroup) are hoovered on each other. That is why I want to add one parent Layout, so I can easily manage these Views.
File1.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DrawView tv = new DrawView(this);
setContentView(tv);
addContentView(tv.btnReset, tv.params);
addContentView(tv.btnScale, tv.paramsRadio);}
DrawView.java
public class DrawView extends View {
public Button btnReset;
public RelativeLayout.LayoutParams params;
public RelativeLayout.LayoutParams paramsRadio;
public RadioGroup btnScale;
public DrawView(Context context) {
super(context);
btnReset = new Button(context);
btnReset.setText("Clear Screen");
btnScale = new RadioGroup(context);
btnScale.setOrientation(RadioGroup.HORIZONTAL);
params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
paramsRadio = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
I omit most of the code because I think its irrelevant, everything works fine but the layout.
Anyway, when I try to create a layout, I simply add a little code:
Changed File1.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DrawView tv = new DrawView(this);
setContentView(tv);
addContentView(tv.layout, tv.params); }
Changed DrawView.java
public class DrawView extends View {
public Button btnReset;
public RelativeLayout.LayoutParams params;
public RelativeLayout.LayoutParams paramsRadio;
public RelativeLayout layout;
public RadioGroup btnScale;
public DrawView(Context context) {
super(context);
btnReset = new Button(context);
btnReset.setText("Clear Screen");
btnScale = new RadioGroup(context);
btnScale.setOrientation(RadioGroup.HORIZONTAL);
params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
paramsRadio = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
layout.addView(btnReset, params);
layout.addView(btnScale, paramsRadio);
I assume that should work like charm, but unfortunately, when I try to do anything with newly created layout, my app crashes. What is wrong with that code?
Well, after quite long fight I managed to solve my own problem :D I did not do it, like #pskink suggested, because honestly for me it was too advanced. I found much simpler solution.
The thing is, You can create as much views as You want in DrawView.java, but sort them in Layout created in File1.java!
Just like that:
File1.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
DrawView tv = new DrawView(this);
ll.addView(tv.btnReset, tv.params);
ll.addView(tv.btnScale, tv.paramsRadio);
ll.addView(tv);
setContentView(ll);
And DrawView.java stays the same:
public class DrawView extends View {
public Button btnReset;
public LinearLayout.LayoutParams params;
public LinearLayout.LayoutParams paramsRadio;
public RadioGroup btnScale;
public DrawView(Context context) {
super(context);
btnReset = new Button(context);
btnReset.setText("Clear Screen");
btnScale = new RadioGroup(context);
btnScale.setOrientation(RadioGroup.HORIZONTAL);
params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
paramsRadio = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);

How to access views by id from tabHost?

I have tabHost widget with dynamic created tabs.
In each of newly created tab, there is relative layout with some views (textView, listView etc).
My question is: how to access to these views and how to append new content there? I tried with setting ids or tags, but i didn't work.
public class Main extends Activity {
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
final TabHost tabs=(TabHost)findViewById(R.id.tabhost);
tabs.setup();
TabHost.TabSpec spec=tabs.newTabSpec("buttontab");
spec.setContent(R.id.form);
spec.setIndicator("Search-form");
tabs.addTab(spec);
Button btn=(Button)tabs.getCurrentView().findViewById(R.id.buttontab);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
final TabHost.TabSpec spec=tabs.newTabSpec("tag1");
spec.setContent(new TabHost.TabContentFactory() {
public View createTabContent(String tag)
{
// Creating a new RelativeLayout
RelativeLayout relativeLayout = new RelativeLayout(Main.this);
// Defining the RelativeLayout layout parameters.
RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.FILL_PARENT);
TextView t = new TextView(Main.this);
// t.setId(12); //This dosen't work
t.setText("Searching in progress. Please wait...");
ListView resultsList = new ListView(Main.this);
//Here: array adapter etc
// Adding the TextView to the RelativeLayout as a child
relativeLayout.addView(t);
relativeLayout.addView(resultsList);
return relativeLayout;
}
});
spec.setIndicator("Tab with results");
tabs.addTab(spec);
new GetData(Main.this).execute();
}
});
}
public void appendResultsToViews(String result)
{
//Here i need to access TextView from tab with specific tag and append results to TextView, which was created dynamically earlier
}
Thank you for your help.
set tag of child view and use findViewWithTag(tag)

Nothing Showing When Dynamically Creating a Relative Layout

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);

Categories