I have this code and i want to add CheckBoxes dynamically inside a LinearLayout that nested inside a ScrollView that nested inside a RelativeLayout( RelativeLayout->ScrollView->LinearLayout->My ChechBoxes)
li = (RelativeLayout) findViewById(R.id.mainlayout);
ScrollView sv = new ScrollView(this);
final LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
li.addView(sv);
sv.addView(ll);
for(int i = 0; i < 20; i++) {
CheckBox cb = new CheckBox(getApplicationContext());
cb.setText("I'm dynamic!");
ll.addView(cb);
}
this.setContentView(sv);
but i get this error:
03-12 20:32:14.840: E/AndroidRuntime(945): Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
My RelativeLayout declared in my XML file already
how i can fix this?
this.setContentView(sv);
This tries to add your ScrollView to the FrameLayout android.R.id.content, but you already made li the parent of sv... hence "The specified child already has a parent."
I believe you can remove this.setContentView(sv); since it looks like you only want to add the ScrollView (et al.) to the RelativeLayout, not replace the entire existing layout.
Check this http://developer.android.com/training/animation/screen-slide.html
When you download the sample app, go through LayoutChangesActivity.java
The following is the code to add an item..
private void addItem() {
// Instantiate a new "row" view.
final ViewGroup newView = (ViewGroup) LayoutInflater.from(this).inflate(
R.layout.list_item_example, mContainerView, false);
// Set the text in the new row to a random country.
((TextView) newView.findViewById(android.R.id.text1)).setText(
COUNTRIES[(int) (Math.random() * COUNTRIES.length)]);
// Set a click listener for the "X" button in the row that will remove the row.
newView.findViewById(R.id.delete_button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Remove the row from its parent (the container view).
// Because mContainerView has android:animateLayoutChanges set to true,
// this removal is automatically animated.
mContainerView.removeView(newView);
// If there are no rows remaining, show the empty view.
if (mContainerView.getChildCount() == 0) {
findViewById(android.R.id.empty).setVisibility(View.VISIBLE);
}
}
});
// Because mContainerView has android:animateLayoutChanges set to true,
// adding this view is automatically animated.
mContainerView.addView(newView, 0);
}
Related
I have an EditText inside of a RelativeLayout (named TopLayout in code below) that is inside of a ListView. There is TextWatcher on the EditText that changes the height of the RelativeLayout (and ListView). But when the height changes, the cursor inside of the EditText moves to the beginning.
Is there anyway to get it to stay where it is?
public void setItemHeight(int itemPos, int itemHeight) {
if (mChallengingThoughtsListView != null) {
View itemView = mChallengingThoughtsListView.getChildAt(itemPos);
LinearLayout topLayout = itemView.findViewById(R.id.TopLayout);
// Set item height
ViewGroup.LayoutParams params = topLayout.getLayoutParams();
params.height = itemHeight;
topLayout.setLayoutParams(params);
// TODO: Put code to place cursor back where it was
}
}
The title may sound confusing I know, I 'm adding a view everytime I click on a button, composed by a textview and a button. I'm setting every added view an ID with simply view.setID(++i) and every added button (inside the views) an ID simply with button.setID(++n), n starting at 1000, since I won't have more than 1000 added views.
Here's what I got:
public class MainActivity extends AppCompatActivity {
GridLayout gridLayout;
static int i;
static int n = 1000;
private Button theButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridLayout = (GridLayout)findViewById(R.id.gamehistory);
Button b = (Button)findViewById(R.id.Button01);
b.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
theButton = new Button(MainActivity.this);
TextView theText = new TextView(MainActivity.this);
theText.setGravity(Gravity.CENTER_HORIZONTAL);
LinearLayout theLayout = new LinearLayout(MainActivity.this);
theLayout.setOrientation(LinearLayout.VERTICAL);
theLayout.setBackgroundColor(Color.parseColor("#8BAAC3"));
theLayout.setId(++i);
theButton.setId(++n);
theButton.setText(theButton.getId() + "");
theText.setText(theLayout.getId() + "");
theLayout.addView(theButton);
theLayout.addView(theText);
gridLayout.addView(theLayout);
GridLayout.LayoutParams lp = (GridLayout.LayoutParams) theLayout.getLayoutParams();
lp.setMargins(10, 10, 10, 10);
}
});
What I need is when I click on a button that was created, the correspondent view is destroyed, and the next views take one step back feeling the gap in the parent which is a GridLayout
Add this where you are adding views to GridLayout -
theLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
gridLayout.removeView(theLayout);
}
});
theButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
gridLayout.removeView(theLayout);
}
});
For this , you need to make theLayout final
final LinearLayout theLayout = new LinearLayout(LauncherActivity.this);
The simplest method would be.
View v = gridLayout.findViewById(<some id>);
gridLayout.removeView(v);
However it seems like you may want to consider using a RecyclerView. You can add/remove items from the Adapter and the views will be updated for you.
EDIT
When using A RecyclerView you have to specify two essential components.
RecyclerAdapter - This converts data into views (rows, cards, cells, ect.)
LayoutManger - Most common are LinearLayoutManger and GridLayoutManager which define how the views from the adapter are presented out in relation to one another, and handle scrolling.
There are a few more option additions you can can use if needed.
ItemDecoration - define backgrounds, or overlays for cells. (E.G. draw a gray background for every other view in a list)
ItemTouchHelper - does most of the heavy lifting for swipe (e.g. swipe to delete) and drag (e.g. drag to re-arrange) operations.
I would highly suggest getting familiar with the RecyclerView it should be your goto component when you need to display a list of items on the screen.
I am making an application which uses ListView to show DB elements. But in the first opening or when user will delete everything DB will be empty and then ListView will show blank screen. I want to show a message when it happens. Not only TextView but also Button. For example "DB now empty. Click on button and try to add some records". ListView 's setEmptyView method allows to add only TextView . Is it really possible to create a layout and show it when ListView is empty?
You can use the property setEmptyView.
If the list is empty and your desired display.
ListView listView = (ListView) findViewById(R.id.lst);
View child = getLayoutInflater().inflate(R.layout.empty_view, null);
((ViewGroup)listView.getParent()).addView(child);
listView.setEmptyView(child);
You can dynamically add a button in the activity layout if your list is empty.
Set onClickListner on the button and override the onClick().
Refer below code:
LinearLayout linear = (LinearLayout)findViewById(R.id.layout);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
Button btn = new Button(this);
btn.setId("btnDynamic");
btn.setText("Go to create entry page");
linear.addView(btn, params);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Toast.makeText(view.getContext(),
"Button clicked index = " + id_, Toast.LENGTH_SHORT)
.show();
}
});
Let me know if this helps.
You can pre-define a layout containing text view and and button as you stated in your question and set it's visibility = gone in your xml or in java code. When the List View will be empty you can set visibility the visibility of the listview.setVisibility(View.GONE) and set your's layout (containing button and a textview) layout.setVisibility(View.VISIBLE)
I'm having a problem with this code. I need to dynamically add buttons to my layout. This code works fine, with one exception. The second button sits on top of the first. This must have something to do with LayoutParams, but I'm not sure what.
private void buttonmaker (Button button)
{
RelativeLayout.LayoutParams rlayout = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
rlayout.addRule(RelativeLayout.CENTER_VERTICAL);
rlayout.addRule(RelativeLayout.ALIGN_LEFT);
rlayout.width = 100;
button.setId(Atom.count);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int id = v.getId();
atoms[id].getname();
TextView textview = (TextView)findViewById(R.id.textView2);
textview.setText(textview.getText()+String.valueOf(atoms[id].getname()));
}
});
if (Atom.count > 1) rlayout.addRule(RelativeLayout.RIGHT_OF,Atom.count-1); else rlayout.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
button.setLayoutParams(rlayout);
RelativeLayout v = (RelativeLayout) findViewById(R.id.rlayout);
v.addView(button);
}
the problem is you set de button in the relativelayout, in this component the objects are being added one above the other, you try create linearlayout global with orientation vertical or horizontal depending on what you want and added buttons, and its all
I'm creating a version of the popular Minesweeper game for Android. I'm trying to programmatically create a button and add it to a RelativeLayout. I've found something very similar here: How do I programmatically add buttons into layout one by one in several lines?
When I try to run it I get a NullPointerException at:
RelativeLayout layout1 = (RelativeLayout) findViewById(R.layout.game);
Here's the whole block of code:
public void create() {
RelativeLayout layout1 = (RelativeLayout) findViewById(R.layout.game);
for(int i = 0; i < gridSize; i++) {
if(grid[i] == 0) { //if grid pos. indicates an empty cell
Button empty = new Button(this);
empty.setBackgroundResource(R.drawable.emptybutton); //set background to empty
empty.setId(i); //set id to value of i
empty.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
layout1.addView(empty); //add the button to the relativeLayout view
//((Button) findViewById(i)).setOnClickListener(emptyListener);
}
Thanks in advance for any responses
have set the layout xml of the Activity by setContentView(R.layout.xxxx)?
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game);
...
this
RelativeLayout layout1 = (RelativeLayout) findViewById(R.layout.game);
should be
RelativeLayout layout1 = (RelativeLayout) findViewById(R.id.relative_id);
R.id... used for mapping control and RelativeLayout is a control.
I think you're getting a blank screen because you haven't set the content view.
What i mean is that the codes does what it's supposed to do however, you should remove the "setContentView()" method at the top and place it at the end, then you should set it to the RelativeLayout before you close the onCreate() method! Something like this:
public void create() {
RelativeLayout layout1 = new RelativeLayout(this);
for(int i = 0; i < gridSize; i++) {
if(grid[i] == 0) { //if grid pos. indicates an empty cell
Button empty = new Button(this);
empty.setBackgroundResource(R.drawable.emptybutton); //set background to empty
empty.setId(i); //set id to value of i
empty.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
layout1.addView(empty); //add the button to the relativeLayout view
//((Button) findViewById(i)).setOnClickListener(emptyListener);
}
}
setContentView(layout1);
}
Also notice that I've changed the declaration of the Relativelayout a little bit.
I hope this helps. :) !
You must enter the ID of the RelativeLayout, not the xml fil name.
try with
RelativeLayout layout1 = (RelativeLayout) findViewById(R.id.yourRelativeLayoutViewID);