Please bear with me as I am new to the use of Views and Layouts.
I am trying to create an application in which the user can enter a text field, press a button and have a new text field appear and they can continue adding text fields in this way.
My solution was to have the top level be a scrollview and then have a relative view as a child within that(this way I can then programatically insert more editviews in my code with the OnClick() listener.
I have seen and read a couple of other posts pertaining to relative views but it seems there is still something that I am missing. I have tried
Here is the xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_create_accounts"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.nic.mybudget.CreateAccountsActivity">
<RelativeLayout
android:id="#+id/activity_create_accounts_relativeLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/activity_name"
android:inputType="textAutoComplete"
android:layout_alignParentTop="true"
android:id="#+id/activity_createAccounts_relativeLayout_activityName"/>
<Button
android:text="+"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_below="#+id/activity_createAccounts_relativeLayout_activityName"
android:id="#+id/activity_create_accounts_relativeLayout_activityName_addButton" />
<Button
android:text="Save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_below="#+id/activity_create_accounts_relativeLayout_activityName_addButton"
android:layout_centerHorizontal="true"
android:id="#+id/activity_create_accounts_relativeLayout_activityName_saveButton" />
</RelativeLayout>
And here is the Code where I try to add new editviews.
public class CreateAccountsActivity extends Activity {
static private final String TAG = "MAIN-Activity";
int numAccounts = 0;
int lastAccountID;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_accounts);
final RelativeLayout Relative = (RelativeLayout) findViewById(R.id.activity_create_accounts_relativeLayout);
final TextView oldAccount = (TextView) findViewById(R.id.activity_createAccounts_relativeLayout_activityName);
final TextView newAccount = new TextView(this);
final Button addNewAccountButton = (Button) findViewById(R.id.activity_create_accounts_relativeLayout_activityName_addButton);
addNewAccountButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i(TAG, "addNewAccountOnClick");
numAccounts = numAccounts+1;
int newAccountID = oldAccount.getId() + numAccounts;
RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);
rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP);
newAccount.setLayoutParams(rlp);
newAccount.setHint("Hint" );
newAccount.setId(newAccountID);
Relative.addView(newAccount);
RelativeLayout.LayoutParams blp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);
blp.addRule(RelativeLayout.BELOW, newAccountID-1);
addNewAccountButton.setLayoutParams(blp);
}
});
}
}
As you can see what I am trying (and failing) to do is add the new edit view at the top of the page and simply push everything else down the page. What am I getting wrong here with the relative layout?
Any help is appreciated.
First thing View with id activity_createAccounts_relativeLayout_activityName is EditText and you are casting it with TextView so that is wrong cast it to EditText.
And to your actual problem:
You are using same EditText instance with variable newAccount and adding it again in relative layout if you want to add one more EditText in relative layout you have to initialise EditText inside onclicklistener.
Just add one line newAccount= new EditText(context)in your onclicklistener code before line numAccounts = numAccounts+1;
Happy Coding !
Related
Earlier on I asked a question about how to reach the last item of a scrollview and someone pointed out that I should be using NestedScrollView, at first it worked but now it's not what I want.
I want to fit my list of item in the ScrollView so only that part of the screen can be scrolled and the other parts stay at their place (the 3 TextView)
So basically my xml file is like this :
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/cl_framgnent_detail_apero"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorPrimary"
tools:context=".ui.home.AperoDetailFragment">
<TextView
android:id="#+id/name_apero"
/>
<TextView
android:id="#+id/date_apero"
/>
<TextView
android:id="#+id/ingredient_title_apero"
/>
<ScrollView
android:id="#+id/rv_apero_ingredient"
android:layout_width="408dp"
android:layout_height="603dp"
android:fillViewport="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="#+id/ingredient_title_apero"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/ingredient_title_apero"
app:layout_constraintVertical_bias="1.0">
<LinearLayout
android:id="#+id/vertical_layout_ingredient"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
And in my Java code I try to populate my list with the following code :
public class AperoDetailFragment extends Fragment {
private View root;
private Apero detailApero;
public AperoDetailFragment(Apero apero) {
this.detailApero = apero;
}
#Override
public View onCreateView(#NonNull final LayoutInflater inflater,
final ViewGroup container, Bundle savedInstanceState) {
root = inflater.inflate(R.layout.fragment_detail_apero, container, false);
TextView name = (TextView) root.findViewById(R.id.name_apero);
name.setText(detailApero.getName());
TextView date = (TextView) root.findViewById(R.id.date_apero);
date.setText(detailApero.getDate());
LinearLayout ll = (LinearLayout) root.findViewById(R.id.vertical_layout_ingredient);
LinearLayout a = new LinearLayout(root.getContext());
ConstraintLayout.LayoutParams lparams = new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_PARENT, ConstraintLayout.LayoutParams.MATCH_PARENT);
a.setLayoutParams(lparams);
a.setOrientation(LinearLayout.VERTICAL);
for (int i = 0; i < 20; i++) {
Button b = new Button(root.getContext());
b.setText("Button " + i);
a.addView(b);
}
ll.addView(a);
return root;
}
}
The problem is that the item are covering the whole screen instead of staying in the parent container (ScrollView) :
How can I fit my list of item to stay in the parent ?
If this is your actual code, then it might help to set constraints to the text views too.
Also, if your ScrollView has a fixed height, then you should remove either the top or bottom constraint. So if you want it to stick to the bottom, remove the top constraint.
I solved this with removing the ScrollView and using a ListView
my problem I know is simple, but for the life of me I cant get an answer...
I have a LinearLayout that got a scrollview inside it... in the scroll view (in code) it should call a custom ScrollView to show on the application... it only shows black, nothing in it... here is my code
first the xml... simple LL with a textview, scrollview and button
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView android:layout_height="wrap_content"
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:text="test field" android:layout_alignParentTop="true"/>
<ScrollView android:layout_width="600dp"
android:layout_height="300dp"
android:id="#+id/v1"
android:fillViewport="true"/>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/gfx"
android:text="Gfx"
></Button>
</LinearLayout>
Now the onCreate of that activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
cw = getWindowManager().getDefaultDisplay().getWidth();
ch = getWindowManager().getDefaultDisplay().getHeight();
v = Draw2d findViewById(R.id.v1);
context = this;
setContentView(R.layout.gfx);
mDbHelper = new DbAdapter(this);
mDbHelper.open();
}
Draw2d is the class of the custom scrollView declared like so (it does have onDraw and everything. If I set the contentview to the Draw2d object directly it'll show no problem, but I need it withen a LL)
public static class Draw2d extends ScrollView{
public Draw2d(Context context) {
super(context);
}
Please any help is appreciated
Maybe because of you have nothing in the ScrollView? Try putting something in it. Check this link, you see there is another linear layout in the scrollview with "30px" layout height making the scrollview appear. If the layout_height was wrap_content, you would not see the scrollview if there is enough place on the screen for it.
I want to show two views in one activity. If I clicked on button in the first view I want to see the second and other way round.
The views should not have the same size as the screen so I want e.g. to center it, like you see in first.xml.
But if I add the views with
addContentView(mFirstView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
the views are not centered. They are shown at top left.
How can I use the xml settings to e.g. center it?
first.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:background="#drawable/background"
android:layout_gravity="center"
android:minWidth="100dp"
android:minHeight="100dp"
android:paddingBottom="5dp"
>
<LinearLayout android:id="#+id/head"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageButton android:id="#+id/first_button"
android:src="#drawable/show_second"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#null" />
</LinearLayout>
second.xml same as first.xml but with
<ImageButton android:id="#+id/second_button"
android:src="#drawable/show_first"
... />
ShowMe.java
public class ShowMe extends Activity {
View mFirstView = null;
View mSecondView = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initFirstLayout();
initSecondLayout();
showFirst();
}
private void initFirstLayout() {
LayoutInflater inflater = getLayoutInflater();
mFirstView = inflater.inflate(R.layout.first, null);
getWindow().addContentView(mFirstView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
ImageButton firstButton = (ImageButton)mMaxiView.findViewById(R.id.first_button);
firstButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
ShowMe.this.showSecond();
}
});
}
private void initSecondLayout() {
// like initMaxiLayout()
}
private void showFirst() {
mSecondView.setVisibility(View.INVISIBLE);
mFirstView.setVisibility(View.VISIBLE);
}
private void showSecond() {
mFirstView.setVisibility(View.INVISIBLE);
mSecondView.setVisibility(View.VISIBLE);
}}
Hope someone can help.
Thanks
Why don't you use setContentView(R.layout.yourlayout)? I believe the new LayoutParams you're passing in addContentView() are overriding those you defined in xml.
Moreover, ViewGroup.LayoutParams lacks the layout gravity setting, so you would have to use the right one for the layout you're going to add the view to (I suspect it's a FrameLayout, you can check with Hierarchy Viewer). This is also a general rule to follow. When using methods that take layout resources as arguments this is automatic (they might ask for the intended parent).
With this consideration in mind, you could set your layout params with:
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(/* wrap wrap */);
lp.setGravity(Gravity.CENTER);
addContentView(mYourView, lp);
But I would recommend setContentView() if you have no particular needs.
EDIT
I mean that you create a layout like:
~~~/res/layout/main.xml~~~
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="....."
android:id="#+id/mainLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
then in your onCreate() or init...Layout():
setContentView(R.layout.main);
FrameLayout mainLayout = (FrameLayout)findViewById(R.id.mainLayout);
// this version of inflate() will automatically attach the view to the
// specified viewgroup.
mFirstView = inflater.inflate(R.layout.first, mainLayout, true);
this will keep the layout params from xml, because it knows what kind it needs. See reference.
I have an android xml layout, main.xml. I would like to add controls to this layout at runtime (I would like to add a series of additional linear layouts that contain buttons controls). Can I do that and if yes, how?
Thanks
I see the error u r doing here
LinearLayout mainLayout = (LinearLayout) findViewById(R.layout.main);
You r taking the layout as Linearlayout object, you should take the LinearLayout id
Try this
LinearLayout lnr = (LinearLayout) findViewById(R.id.LinearLayout01);
Button b1 = new Button(this);
b1.setText("Btn");
lnr.addView(b1);
You can add controls programmatically if you want in your code, or even another XML with a View and an Inflater.
Here you can read the basics: http://developer.android.com/guide/topics/ui/declaring-layout.html
Ok, I have got it to work.
The steps are the following:
First inflate the xml layout, ie,
View view = View.inflate(this, R.layout.main, null);
Then instantiate the container object from the xml layout into a ViewGroup class, ie,
ViewGroup container = (ViewGroup) view.findViewById(R.id.myContainer);
Then create a linearLayout object, create and add onto that any controls needed, add the linearLayout to the container object and use setContentView on the view object, ie,
container.addView(buttonsLayout);
this.setContentView(view);
You can do this quite easy by setting an id on the layout on which you want to add views to. Say your main.xml look like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="#+id/label"
android:layout_width="fill_parent"/>
<LinearLayout android:id="#+id/container"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</LinearLayout>
</LinearLayout>
Lets assume that you want to add your additional views to the LinearLayout with id id/container. In your onCreate method you could retrieve that object for later use:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContainer = (ViewGroup)view.findViewById(R.id.container);
}
Now you are all set to add other views to your container ViewGroup:
LinearLayout theButtons = getButtons()
mContainer.addView(theButtons);
In the getButtons method you need to create your LinearLayout containing the buttons you need. Either you do this programmatically or by inflating a view defined in an XML file. See LayoutInflater.inflate.
just try this:
LinearLayout mainLinearLayout = (LinearLayout) findViewById(R.layout.llmain);
now create button dynamically like this
Button btn1 = new Button(this);
btn1.setText=("Button 1");
mainLinearLayout .addView(btn1);
now if you want to add onether linearlayout then add it below button then
LinearLayout llinner = new LinearLayout(this);
Button btn2 = new Button(this);
btn2.setText=("Button 2");
mainLinearLayout .addView(btn2);
llinner.addView(btn2 );
mainLinearLayout .addView(llinner);
Try this :
LinearLayout ll =(LinearLayout)findViewById(R.id.linlay);
Button b = new Button(this);
b.setText("Hello");
l.addView(b);
This might help you
Here is what I did to display a set of runtime buttons on table layout.
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View view = View.inflate(this, R.layout.activity_main, null);
TableRow myrow = (TableRow) view.findViewById(R.id.myrow);
Button btn1 = new Button(this);
btn1.setText("Button 1");
myrow .addView(btn1);
Button btn2 = new Button(this);
btn2.setText("Button 2");
myrow .addView(btn2);
this.setContentView(view);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ScrollView
android:id="#+id/myview"
android:layout_width="404dp"
android:layout_height="691dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TableLayout
android:id="#+id/mylayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TableRow android:id="#+id/myrow"></TableRow>
</TableLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
AVD Pixel4API30
Output screenshot
I'm new to android platform , I'd like to settext using textviews , I tried to write set text into two textviews but its just draws one textview why?
I can't draw two textviews
TextView tv1;
TextView tv2;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
layout = new LinearLayout(this);
tv1 = new TextView(this);
tv2 = new TextView(this);
tv1.setText("Hello");
tv2.setText("How are you?");
}
On Android, the user interface normally should be created using XML-files, instead of Java code. You should read up on the tutorials on android.com, especially:
http://developer.android.com/guide/topics/ui/declaring-layout.html
An example:
In your res/layout/main.xml, you define the text TextView's:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView android:id="#+id/TextView1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="TextView 1"/>
<TextView android:id="#+id/TextView2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="TextView 2"/>
</LinearLayout>
Then if you use setContentView in the activity to display this, the app will show to TextView's:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.main);
}
If you want to programmatically set the text in the Activity, just use findViewById():
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.main);
((TextView)this.findViewById(R.id.TextView1)).setText("Setting text of TextView1");
}
I definitely second TuomasR's suggestion to use XML layouts. However, if you're wanting to add new TextViews dynamically (i.e. you don't know how many you will need until runtime), you need to do a couple of other steps to what you are doing:
First, define your LinearLayout in main.xml (it's just easier that way than LayoutParams, IMO):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/my_linear_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
/>
Now, you can go to your code, and try the following:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//This inflates your XML file to the view to be displayed.
//Nothing exists on-screen at this point
setContentView(R.layout.main);
//This finds the LinearLayout in main.xml that you gave an ID to
LinearLayout layout = (LinearLayout)findViewById(R.id.my_linear_layout);
TextView t1 = new TextView(this);
TextView t2 = new TextView(this);
t1.setText("Hello.");
t2.setText("How are you?");
//Here, you have to add these TextViews to the LinearLayout
layout.addView(t1);
layout.addView(t2);
//Both TextViews should display at this point
}
Again, if you know ahead of time how many views that you need, USE XML.