I am trying to create a LinearLayout programmatically from information contained in an Array.
Let me explain :
I create a professional application that will not be on PlayStore.
I have the following Array, manually populated, (a kind of global variable):
static final String[][] reseaux = new String[][] {
{"Net1","192.168.0.1"},
{"Net2","192.168.10.1"},
{"Net3","192.168.20.1"},
{"Net4","192.168.30.1"}
};
For some customers, it contains only one entry :
static final String[][] reseaux = new String[][] {
{"Net1","192.168.0.1"}
};
According to the Array containing only one entry, I created the following layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/welcome"
android:layout_gravity="center"
xmlns:android="http://schemas.android.com/apk/res/android"
tools:ignore="Overdraw">
<include
android:id="#+id/tool_bar"
layout="#layout/tool_bar" />
<ScrollView
android:layout_height="match_parent"
android:layout_width="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="#+id/linearLayout"
android:layout_marginTop="15dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false">
<LinearLayout
android:id="#+id/linearLayoutTest"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
And the code :
LinearLayout l = findViewById(R.id.linearLayoutTest);
for (int i = 0; i < reseaux.length; ++i) {
final int id = i;
ImageButton resBtn = new ImageButton(this);
TextView tv = new TextView(this);
tv.setGravity(Gravity.CENTER | Gravity.BOTTOM);
tv.setText(reseaux[i][0]);
resBtn.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.button_reseaux));
resBtn.setBackgroundColor(getResources().getColor(R.color.transparent));
l.addView(resBtn);
l.addView(tv);
resBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Check network
if (CheckNetworkStatus.isNetworkAvailable(getApplicationContext())) {
Intent i = new Intent(getApplicationContext(),
HomeReseauActivity.class);
startActivity(i);
BASE_URL = null;
nomReseau = null;
BASE_URL = reseaux[id][1];
nomReseau = reseaux[id][0];
} else {
//Error message if no network connexion
if (toastMessage != null) toastMessage.cancel();
toastMessage = Toast.makeText(HomeActivity.this, getString(R.string.networkError), Toast.LENGTH_LONG);
toastMessage.show();
}
}
});
Give me the following result that suits me perfectly :
Now, when I have multiple entries in my Array, here's what I get :
This does not suit me. I will like horizontal lines of three icons. When a line is filled, it creates a new line of three icons, etc.
Here is a quick edit with paint to demonstrate what I want:
I think the solution must be simple .. but I can not get this result.
Be indulgent with my code, I learn everything by myself and there is surely a better way to write :-)
Hoping someone can help me!
As stated in the comments of my question, the solution was to use RecyclerView and GridLayoutManager.
For future readers, this link has helped me a lot!
Thanks to everyone who answered my question.
Related
I've been struggling with finding an appropiate answer on how to add components to a layout in a fragment at runtime in android studio.
Specifically:
I have Class A which downloads and parses an XML file. Fragment B instantiates this Class A and should display those downloaded items. (just a textview for now)
This is the XML file in which the textView should be displayed. The items should be displayed in two columns. I know how to create the layout in the XML File but I have no idea on how to do it programatically. I've also read something about inflaters but I dont know if it fits this purpose.
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TableRow
android:layout_width="match_parent"
android:layout_height="0dp"
android:paddingTop="10dp">
<TextView
android:id="#+id/columnItem"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:layout_marginStart="5dp"
android:layout_weight=".5"
android:background="#c5c5c5"
android:gravity="center"
android:text="#string/CategoryLeft" />
</TableRow>
</ScrollView>
</TableLayout>
So here is the Code in Fragment B which currently just changes the text of the two existing textviews, that works just fine.
public void onStart() {
super.onStart();
ArrayList<String> categories = new ArrayList<>();
XMLHandler getXML = new XMLHandler();
getXML.execute();
categories = getXML.getCategories();
Iterator<String> it = categories.iterator();
while (it.hasNext()) {
System.out.println("Data is " + it.next());
columnItem.setText(it.next());
}
}
The goal is to add a new TextView for each iteration through the while loop to the parent layout. This TextView should display the content of it.next().
Thanks in advance and let me know if u need any further information.
If you want to add a TextView to TableRow.
First, add an id to TableRow
<TableRow
android:id="#+id/table1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:paddingTop="10dp">
Then, in your onCreate
tableRow = findViewById(R.id.table1); // tableRow is a global variable
add a void in your fragment
private void addTextView(String atext) {
TextView txt = new TextView(getActivity());
txt.setText(atext);
tableRow.addView(txt);
// here you can add other properties to the new TextView (txt)
}
and then
public void onStart() {
super.onStart();
ArrayList<String> categories = new ArrayList<>();
XMLHandler getXML = new XMLHandler();
getXML.execute();
categories = getXML.getCategories();
Iterator<String> it = categories.iterator();
while (it.hasNext()) {
String atxt = it.next();
System.out.println("Data is " + atxt);
addTextView(atxt);
}
}
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 !
My Android game project needs a "New Game" activity. The game has a couple of options that should be asked each time a new game is started: the board size and the game seed. I would like to do this in a form resembling the standard "Settings" activity, but with an added "Start" button at the bottom. Given that these things will be chosen every new game, they don't want to be hidden away in the app's Settings activity. So what's the best way to go about this?
Things I've investigated:
Using a custom PreferenceActivity, since the behaviour is almost the same. Since the PreferenceActivity doesn't use layout XML files I can't see a way of adding a button to it.
A Linear layout that includes a ListView and a Button. I've started implementing this, but I can't even find a way to add items to the ListView - the ListView guide in the documentation certainly isn't aimed at a beginner like me! And then the list items need to be interactive to allow options to be selected: this looks like a lot of work to duplicate what PreferenceActivity almost does on its own.
Is there an option that I'm missing? I've spent a couple of hours trying to find an answer in the documentation and in previous questions, but with no progress. If anyone can point me in the right direction I'd be grateful.
Here is some code for you. Hope it will be useful.
You should go by the second way and use LinearLayout (this is main.xml):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ListView
android:id="#+id/lvSimple"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
<Button // describe your start button here/>
</LinearLayout>
Layout for ListView item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="#+id/ivImg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher">
</ImageView>
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<CheckBox
android:id="#+id/cbChecked"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CheckBox">
</CheckBox>
<TextView
android:id="#+id/tvText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginRight="20dp"
android:text="TextView">
</TextView>
</LinearLayout>
</LinearLayout>
Your MainActivity.java:
public class MainActivity extends Activity {
// имена атрибутов для Map
final String ATTRIBUTE_NAME_TEXT = "text";
final String ATTRIBUTE_NAME_CHECKED = "checked";
final String ATTRIBUTE_NAME_IMAGE = "image";
ListView lvSimple;
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// data array
String[] texts = { "sometext 1", "sometext 2", "sometext 3",
"sometext 4", "sometext 5" };
boolean[] checked = { true, false, false, true, false };
int img = R.drawable.ic_launcher;
// our data source
ArrayList<Map<String, Object>> data = new ArrayList<Map<String, Object>>(
texts.length);
Map<String, Object> m;
for (int i = 0; i < texts.length; i++) {
m = new HashMap<String, Object>();
m.put(ATTRIBUTE_NAME_TEXT, texts[i]);
m.put(ATTRIBUTE_NAME_CHECKED, checked[i]);
m.put(ATTRIBUTE_NAME_IMAGE, img);
data.add(m);
}
String[] from = { ATTRIBUTE_NAME_TEXT, ATTRIBUTE_NAME_CHECKED,
ATTRIBUTE_NAME_IMAGE };
// array of IDs of Views
int[] to = { R.id.tvText, R.id.cbChecked, R.id.ivImg };
// create adapter
SimpleAdapter sAdapter = new SimpleAdapter(this, data, R.layout.item,
from, to);
// create ListView and set the adapter
lvSimple = (ListView) findViewById(R.id.lvSimple);
lvSimple.setAdapter(sAdapter);
}
}
I am attempting to achieve a result similar to:
Where contacts might or might not have email addresses or other profile information. Is it possible to achieve the majority of it through XML or does it all need to be done through Java?
Here is the pseudocode that I imagine would be a solution:
if (contact.hasPhoneNumber)
foreach number in contact
inflate r.layout.contact_number
settext phonenumber textview
add view to layout
Is there a smarter approach?
This was solved by having the following:
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/contactContent"
android:layout_below="#+id/profile_background">
<LinearLayout android:orientation="vertical" android:id="#+id/c_detail_content_main" android:paddingBottom="50.0dip" android:layout_width="fill_parent" android:layout_height="wrap_content">
<LinearLayout android:orientation="vertical" android:visibility="gone" android:id="#+id/c_detail_birthday_layout" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="20.0dip">
</LinearLayout
</ScrollView>
And the following code:
if (this.contact.hasPhoneNumber())
{
LinearLayout phoneNumberContent = (LinearLayout) view.findViewById(R.id.c_detail_phone_layout);
phoneNumberContent.setVisibility(View.VISIBLE);
for (PhoneNumber number : this.contact.getPhoneNumbers())
{
LinearLayout tempNumberContent = new LinearLayout(this.getActivity().getApplicationContext());
TextView type = new TextView(this.getActivity().getApplicationContext());
TextView phoneNo = new TextView(this.getActivity().getApplicationContext());
type.setWidth(LayoutTools.getDPMeasurement(this.getActivity(), 85));
phoneNo.setText(number.getNumber());
tempNumberContent.addView(type);
tempNumberContent.addView(phoneNo);
phoneNumberContent.addView(tempNumberContent);
}
}
I have multiple textviews in main.xml
<LinearLayout...
>
<textview adndroid:tag="A">
...
till to Z.
</LinearLayout>
I need an fastscroll over all the textViews . How to do that? Need some help.
I have to print the character when pressing A or B..and so on. How to do that?
a1.setOnTouchListener(newOnTouchListener(){
public boolean onTouch(View w,MotionEvent event)
{
//? WHAT TO WRITE HERE?
I NEED TO PRINT ON THE SCREEN A because I CLICK ON A TEXTVIEW.
I LIKE TO PRINT THE CHARACTER A IN A BOX (like the one from contact list android)
}
});
Here is an example code: link
You can do:
<ScrollView android:id="#+id/ScrollView02"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
....
>
<textview ...yourtextview >
...
</LinearLayout>
</ScrollView>
For the second part of your question, I think you have to add android:clickable="true" to all your textViews and handle that with code.
Otherwise, you could use a ListView with the setOnItemClickListener(new OnItemClickListener(), in this way it's easier ...
At first specify layout for chars in xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/list_products"
android:fastScrollEnabled="true"
/>
<LinearLayout
android:orientation="vertical"
android:id="#+id/chars_layout"
android:layout_width="26dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_alignParentEnd="true"
>
</LinearLayout>
</RelativeLayout>
Then in code add chars to your layout:
private void addCharsForScrolling(LinearLayout charsLayout, ArrayList<String> sectionList) {
Collections.sort(sectionList);
sections = new String[sectionList.size()];
for (int m = 0; m < sectionList.size(); m++) {
sections[m] = sectionList.get(m);
addScrollText(charsLayout, sectionList.get(m),false);
}
}
Here is code for sectionlist:
private void findChars (ArrayList<BrandsRestaurantsModel> brands, ArrayList <ProductLists.ResourantsWithPlace> imgstructure){
LinearLayout charsLayout = (LinearLayout) this.rootview.findViewById(R.id.chars_layout);
mapIndex = new LinkedHashMap<String, Integer>();
sectionList = new ArrayList<String>();
for (int x = 0; x < brands.size(); x++) {
sectionList.add(brands.get(x).getCh());
if (!mapIndex.containsKey(brands.get(x).getCh()))
mapIndex.put(brands.get(x).getCh(), x);
}
Set<String> sectionLetters = mapIndex.keySet();
ArrayList<String> sectionList = new ArrayList<String>(sectionLetters);
addCharsForScrolling(charsLayout, sectionList);
}