Optimize code - create custom text view from array and assign value - android

This code generate some textview and assign value to it using an array.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_list);
LinearLayout myLayout = (LinearLayout) findViewById(R.id.llContainer2);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
int textViewCount = 24;
TextView[] pairs=new TextView[textViewCount];
for(int i=0; i<textViewCount; i++)
{
pairs[i] = new TextView(this);
pairs[i].setLayoutParams(lp);
pairs[i].setId(i);
pairs[i].setText(getString(R.string.t1));
//--------------------
pairs[i].setClickable(true);
pairs[i].setOnClickListener(this);
pairs[i].setTextColor(Color.parseColor("#4682B4"));
pairs[i].setTextSize(TypedValue.COMPLEX_UNIT_DIP, 21);
pairs[i].setPadding(8,8,8,8);
//------------------
myLayout.addView(pairs[i]);
}}
I found these codes inside //-- and //-- is repeatative.
I am finding way to optimise it.
My thinking
1. inflate textview layout inside the loop and using a customlayout.xml
2. set the layout once on the start, so it inherent the layout from parent
Tried
LayoutInflater layoutInflater =
(LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View child = getLayoutInflater().inflate(R.layout.style_textview, null);
myLayout.addView(child);
//------------------------------
LinearLayout container = (LinearLayout)
findViewById(R.id.llContainer);
View inflatedLayout= getLayoutInflater().inflate(R.layout.style_textview, null);
container.addView(inflatedLayout);
Anyone can show me how to use the xml inside loop or inflate the parent.
Secondly, how to use
public void onClick(View v) {
switch (v.getId()){
case R.id.i:
//start activity
}}
I am open to better suggestion.

Inflate the view like this:
pairs[i] = (TextView) LayoutInflater.from(this).inflate(R.layout. style_textview, myLayout, false);
// Don't set Id by a code-defined value like this, use setTag for additional data or use View.generateViewId()
pairs[i].setId(i);
pairs[i].setText(getString(R.string.t1));
pairs[i].setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
// Do stuff
}
}
myLayout.addView(pairs[i]);
LayoutParams and other properties are defined in xml

Related

Is there a way to change background color behind a button (button.setBackgroundResource)

I'm a new Android dev student, and I'm trying to create a dynamic layout witch contains a TextView and a button inside the same row.
but I have a little problem.
I set my Button in my Drawables ressources by
button.setBackgroundResource(R.drawable.ic_comment_black_48px);
and now, I cannot change the backgroundcolor behind it.
I have created a newLinearlayout inside my main LinearLayout and have created a new textView and a new Button.
I have put them inside the LinearLayout's child and put it inside the main.
That's work but not the background color behind my button.
is there a way to do that?
my xml layout
<?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="vertical"
android:background="#color/grey"
android:id="#+id/historyLayout">
</LinearLayout>
my complete activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_history);
mLinearLayout = findViewById(R.id.historyLayout);
mMoodSaved = new ArrayList(7); // Define the max size of my ArrayList
loadData();
for (int i = 1; i <= 7; i++) {
final TextView textView = new TextView(this);
mLinearLyt = new LinearLayout(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
mLinearLyt.setOrientation(LinearLayout.HORIZONTAL);
textView.setHeight(300);
textView.setWidth(400);
textView.setBackgroundColor(Color.RED);
textView.setTextColor(Color.BLACK);
textView.setTextSize(12);
textView.setText(String.valueOf(i));
mLinearLyt.setBackgroundColor(Color.YELLOW);
mLinearLyt.addView(textView);
mLinearLyt.setLayoutParams(params);
ImageButton button = new ImageButton(this);
LinearLayout.LayoutParams param2 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
param2.setMargins(20,50,0,0);
param2.height = 100;
param2.width = 100;
button.setLayoutParams(param2);
button.setBackgroundResource(R.drawable.ic_comment_black_48px);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
soundConfirm();
Toast.makeText(getApplicationContext(), textView.getText(), Toast.LENGTH_LONG).show(); //Display Toast Message
}
});
mLinearLyt.addView(button);
mLinearLayout.addView(mLinearLyt);
}
}
Since this an ImageButton, set
button.setImageResource(R.drawable.ic_comment_black_48px)
instead of setBackgroundResource.

Find child of a LinearLayout inside a LinearLayout

I have a LinearLayout ("ll") that is already created in xml and the app dynamically creates another LinearLayout inside of it and creates an EditText and a Button inside of that view. The button makes the whole LinearLayout destroy itself along with the EditText and Button inside it (the whole system is a player name entering activity). Anyway, I am trying to find a way to get the text from all of the EditTexts. I have tried using a for loop on "ll" and using ll.getChildAt() but I can't seem to use .getChildAt() on whatever ll.getChildAt() generates because getChildAt() generates a "View" not a "LinearLayout." I basically just need a way to search two children in, rather than just one. Also, if there is just a better way I should be doing this, let me know. I'm open to suggestions.
Here's my code if it will help:
NewGameCreate.java
public class NewGameCreate extends Activity {
int numOfPlayers = 0;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.new_game_create);
}
public void newPlayer(View view) {
numOfPlayers++;
final LinearLayout ll = findViewById(R.id.playerView);
final LinearLayout llNew = new LinearLayout(getApplicationContext());
llNew.setOrientation(LinearLayout.HORIZONTAL);
llNew.setId(numOfPlayers);
ll.addView(llNew);
EditText newName = new EditText(this);
newName.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1));
newName.setHint("Enter Player Name");
newName.setId(numOfPlayers);
newName.setWidth(0);
llNew.addView(newName);
final Button delete = new Button(this);
delete.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 0));
delete.setText("Delete");
delete.setId(numOfPlayers);
delete.setWidth(0);
delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int id = delete.getId();
ll.removeViewInLayout(findViewById(id));
Drawable back = ll.getBackground();
ll.setBackgroundColor(00000000);
ll.setBackground(back);
ll.invalidate();
}
});
llNew.addView(delete);
}
public void startGame(View view){
LinearLayout ll = findViewById(R.id.playerView);
List text = new ArrayList();
for(int loop = 0; loop < ll.getChildCount(); loop++) {
//this is the code in question and where I want to get the text from
//all my EditTexts
LinearLayout inner = ll.getChildAt(loop);
}
}
}
I think I found the answer to it. You need to change a little bit of code in the startGame() method I m providing the code for startGame below.
public void startGame(View view) {
LinearLayout ll = findViewById(R.id.playerView);
List text = new ArrayList();
for (int loop = 0; loop < ll.getChildCount(); loop++) {
//this is the code in question and where I want to get the text from
//all my EditTexts
LinearLayout inner = (LinearLayout) ll.getChildAt(loop);
for (int j = 0; j < inner.getChildCount(); j++) {
if (inner.getChildAt(j) instanceof EditText) {
EditText textET = (EditText) inner.getChildAt(j);
Log.d("TAG",textET.getText().toString());
}
}
}
}
In the above code you were able to get the first child only but as you have added a linearLayout with orientation Horizontal in a parent LinearLayout with orientation Vertical, you have written code for the child of parent layout i.e playerView. I have modified the code to get the elements of the child Linear layout and Log prints all the text from the EditText.
Hope that helps!!

Adding Layout dynamically for number of times on button click

The scenario is, When the user clicks the button, I need to add
particular layout in known position of parent layout for the number of times button clicked.
I don't know whether it works or not. I tried this following solution which I got from other posts
Buttononclicklistenercode is,
parent = (ViewGroup) C.getParent();//c is a layout in which position i want to add view
final int index = parent.indexOfChild(C);
tobeadded=getLayoutInflater().inflate(R.layout.block_tobeadded_foremi,null);
((Button)findViewById(R.id.button88)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addviewcount+=1;
LinearLayout addinglayout=new LinearLayout(MyActivity.this);
addinglayout.setOrientation(LinearLayout.VERTICAL);
parent.removeViewAt(index);
addinglayout.removeAllViews();
for(int i=0;i<addviewcount;i++)
addinglayout.addView(tobeadded);
parent.addView(addinglayout, index);
}
});
But I am getting java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. In my code, before adding that layout, I have invoked the method removeViewAt() for parent.
Can anyone help me to know what is wrong in that.And Is there any other way to do this? Thanks in advance!
You are getting an IllegalStateException because you've already attached the child to the root of the layout.
parent.removeViewAt(index);
addinglayout.removeAllViews();
for(int i=0;i<addviewcount;i++)
addinglayout.addView(tobeadded);//Exception in this line
parent.addView(addinglayout, index);
Let's say addviewcount is 2.
Now in the first iteration, tobeadded is attached to addinglayout.
In the second iteration, you're again trying to attach tobeadded to addinglayout which results in an exception, since The specified child already has a parent. To solve this, You must call removeView() on the child's parent first.
All in all no child is supposed to have more than one parent. And the way you're implementing what you're trying to do is wrong. Create an array of View objects and attach them to the layout in a loop. This will solve your problem.
Here's a link where I've answered a similar question in detail few months back.
https://stackoverflow.com/a/46672959/2356570
LinearLayout.LayoutParams lparams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);
On Click of button try this:
addinglayout.removeAllViews();
View text = new View(context);
textNotes.setLayoutParams(lparams);
addinglayout.addView(text);
public class SampleDynamiclay extends AppCompatActivity {
Button add, replace;
LinearLayout dynamiclay;
int newid = 100;
int replaceid;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sampledynamiclay);
add = (Button) this.findViewById(R.id.add);
replace = (Button) this.findViewById(R.id.replace);
dynamiclay = (LinearLayout) this.findViewById(R.id.dynamiclay);
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
TextView txt = new TextView(SampleDynamiclay.this);
txt.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
newid = newid + 1;
txt.setTag(newid + "");
txt.setTextColor(getResources().getColor(R.color.black));
txt.setText("TextView " + newid);
dynamiclay.addView(txt);
}
});
replace.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
newid = newid + 1;
View removableView = dynamiclay.getChildAt(2);
dynamiclay.removeView(removableView);
TextView txt = new TextView(SampleDynamiclay.this);
txt.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
txt.setTag(newid + "");
txt.setTextColor(getResources().getColor(R.color.black));
txt.setText("TextView is replaced " + newid);
dynamiclay.addView(txt, 2);
}
});
}
}

Find out which view is touching in multiple layouts in linearlayout in android?

I have to create layout dynamically using Java.
I have created 9 linear layouts dynamically as below:
for (int i=0;i<10;i++)
{
Element e = (Element) nl.item(i);
cpName = parser.getValue(e,"coverpage");
System.out.println("coverpage name :" + cpName);
LinearLayout lbottomLayoutu1=new LinearLayout(getApplicationContext());
lbottomLayoutu1.setGravity(Gravity.CENTER);
LinearLayout.LayoutParams layoutParams1u1= new LinearLayout.LayoutParams(width,height/4);
layoutParams1u1.weight=1.0f;
lbottomLayoutu1.setLayoutParams(layoutParams1u1);
lbottomLayoutu1.setBackgroundColor(Color.RED);
lbottomLayoutu1.setBackgroundResource(R.drawable.image);
linearLayout.addView(lbottomLayoutu1);
ImageView iv1=new ImageView(getApplicationContext());
LinearLayout.LayoutParams layoutParams= new LinearLayout.LayoutParams(width/4,height/4);
iv1.setLayoutParams(layoutParams);
iv1.setImageResource(R.drawable.coverpage3);
lbottomLayoutu1.addView(iv1);
lbottomLayoutu1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("Calling coverpage");
String Url = WebUrl+cpName;
System.out.println("web Url: " + Url);
Intent in = new Intent(getApplicationContext(),CurlActivity.class);
Bundle bundle = new Bundle();
bundle.putString("Image Url",Url);
in.putExtras(bundle);
startActivity(in);
}
});
setContentView(linearLayout);
}
I put a touch event for every layout. But if I touch any layout how can I know which layout is touching?
I think it's better to use custom listView (like here http://www.codeproject.com/Articles/507651/Customized-Android-ListView-with-Image-and-Text)
You need to set the ids of each layout as
obj.setId(i)
so that in your touch event you can identify it with
int id=obj.getId()
and work accordingly!
If you implement the OnClickListener for the view, like you did...
lbottomLayoutu1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// ...
}
}
... the parameter View v tells you which layout has been touched. You can then cast it to your expected layout, like:
LinearLayout clickedLayout = (LinearLayout) v;
This will be the layout that has been clicked.
If you want, however, know the index that you used in the loop, you have to overwrite your LinearLayout and give it a member that holds the index. Then you can cast it to your custom LinearLayout class and get the index. (If you need more help on this, let me know in the comments).

OnClick button ,create a layer in the same form. Android

I m very new to Android.
I want to create a dynamic OnClick button functionality.
OnClick of "+" above , it should create a other layer , like this below.
My confusion , my entire design UI is in layout.xml.
How we can we include another layer in our UI on OnClick of "+" button.
Any input would be helpful.
Thanks !!!
You could do this programatically. XML is for static layouts.
Excuse my pseudo Android:
private LinearLayout root;
public void onCreate(Bundle b){
LinearLayout root = new LinearLayout(this);
root.addChild(createGlucoseReadingView());
setContentView(root);
}
private View createGlucoseReadingView() {
LinearLayout glucoseRoot = new LinearLayout(this);
glucoseRoot.addChild(new TextView(this));
return glucoseRoot;
}
public void onPlusClick(View button){
root.addChild(createGlucoseReadingView());
}
Something along those lines, I've obviosuly left out formatting and adding the layout params to the views, but you get the idea.
In your XML have one Vertical Linear Layout to add and remove EditTexts at runtime, Here I have shown you code I have used in my demos. To handle and maintain the usage.
Onclick of your Add and Minus button click
public void onClick(View view) {
super.onClick(view);
switch (view.getId()) {
case R.id.btnadd:
createTextview(counter);
counter++;
if (counter > 3) {
btnAdd.setVisibility(View.GONE);
btnRemove.setVisibility(View.VISIBLE);
}
break;
case R.id.btnremove:
removeView(counter);
txtoption[counter - 1] = null;
counter--;
if (counter < 3) {
btnAdd.setVisibility(View.VISIBLE);
btnRemove.setVisibility(View.GONE);
}
break;
}
}
Functions to create and remove view
private void createTextview(int index) {
txtoption[index] = new EditText(this);
txtoption[index].setSingleLine(true);
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
param.bottomMargin = 10;
txtoption[index].setLayoutParams(param);
txtoption[index].setBackgroundResource(R.drawable.textbox);
txtoption[index].setTypeface(ttfDroidSherif);
lnpolloptions.addView(txtoption[index]);
}
private void removeView(int index) {
lnpolloptions.removeView(txtoption[index - 1]);
}
Your vertical LinearLayout to contain all the edittext childs
LinearLayout lnpolloptions = (LinearLayout) findViewById(R.id.lnpolloptions);
Arrays of edittext to be created of removed at runtime
private EditText[] txtoption = new EditText[4];
Onclick of submit to get value from each textbox
int length = txtoption.length;
for (int i = 0; i < length; i++) {
if (txtoption[i] != null) {
Log.i("Value",""+txtoption[i].getText());
}
}

Categories

Resources