Android: Add programmatically multiple views to linear layout - android

I'm not sure how to handle that. I need linear layout which needs to have 20+ TextView and EditText components. I can define ImageView and buttons on top but I don't know how to generate rest of the components below and then put a button at the end.
It will look something like this:
---Button-----Button-------
--------ImageView----------
TextView -------- EditText
Item1.............[-------]
Item2.............[-------]
Item3.............[-------]
Item4.............[-------]
.
.
.
------------Button------------
There will be really a lot of components so I would like to avoid defining all components by hand in XML. After clicking on button all components need to be saved in pairs "name":"value" ("Item1":"EditText value"). I have a list of item's names and user will write the values for those items and save them to JSON file.
Thank you in advance.

you have to implement a class like this.
public class DetailedTicketSystemView extends LinearLayout
{
static int inc = 100;
ArrayList<XmlScommessaInCorso> _viewData;
ArrayList<xmlSistemaMovimenti> _systems;
Context _context;
public DetailedTicketSystemView(Context context, int res, AttributeSet attrs, ArrayList<XmlScommessaInCorso> viewData, ArrayList<xmlSistemaMovimenti> systems)
{
super(context, attrs);
_context = context;
_viewData = viewData;
_systems = systems;
LayoutInflater.from(context).inflate(res, this, true);
setId(inc);
inc++;
setLayout();
}
private void setLayout()
{
TextView textView;
String text;
for (int i = 0; i < _systems.size(); i++)
{
View quotesView = (View) LayoutInflater.from(_context).inflate(R.layout.row_ticket_detail_system_layout, null, true);
quotesView.setId(i);
// System Id
textView = (TextView) quotesView.findViewById(R.id.systemId);
text = "" + _context.getString(R.string.id_sistema) + " " + _systems.get(i).getAttributeOrVoidString(xmlSistemaMovimenti.ATTR_id) +
" / " + _viewData.size();
textView.setText(text);
// System Columns
textView = (TextView) quotesView.findViewById(R.id.systemColumns);
text = "" + _context.getString(R.string.colonne) + " " + _systems.get(i).getAttributeOrVoidString(xmlSistemaMovimenti.ATTR_n_multiple_sis);
textView.setText(text);
// System Bet Text
textView = (TextView) quotesView.findViewById(R.id.systemBetText);
textView.setText(R.string.importoPerColonna);
// System bet Value
textView = (TextView) quotesView.findViewById(R.id.systemBetValue);
text = "€ " + XmlScommessaInCorso.getQuotaFormattedOrVoid(_systems.get(i).getAttributeOrVoidString(xmlSistemaMovimenti.ATTR_impo_sistema));
textView.setText(text);
LinearLayout primaryLayout = (LinearLayout) findViewById(R.id.primaryLayout);
primaryLayout.addView(quotesView);
}
}
}

Related

Clickable Span onClick not called in EditText

I am trying to create a chat screen and implement # based user annotation inside the message. For which I implmented a ClickableSpan class on the span.There are 3 parts to this problem.
1) While sending the message (inside my EditText), any user annotations a user clicks on should take them to end of the annotation. Example - while typing "#my_user# this is a sample message", if a user touches around _ the cursor should be set at the end of #my_user#|
2) Sent message bubble - annotation should be clickable
3) Received Message bubble - annotation should be clickable
In my case 2. and 3. in the TextView are working. I need to understand what should I do to get 1 to work
Code below:->
Setting the span
editable.setSpan(new UserAnnotationClickableSpan(editable.toString().substring(style.getStart() + keywordLength, style.getEnd() - keywordLength + 1)) , style.getStart() + keywordLength, style.getEnd() - keywordLength + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
UserAnnotationClickableSpan class
private class UserAnnotationClickableSpan extends ClickableSpan{
String text;
public UserAnnotationClickableSpan(String text){
this.text = text;
}
#Override
public void onClick(View view) {
Log.d(Config.LOGTAG, "Clickable area called in text box");
Spanned s;
boolean isEditing = false;
EditMessage em;
TextView tv;
// Notify clickable span handler
if(view instanceof EditMessage){ // then user it typing.
isEditing = true;
em = (EditText) view;
s = (Spanned) em.getText();
int start = s.getSpanStart(this);
int end = s.getSpanEnd(this);
em.setSelection(end);
}else { // its either a
tv = (TextView) view;
s = (Spanned) tv.getText();
int start = s.getSpanStart(this);
int end = s.getSpanEnd(this);
String str = tv.getText().toString().trim();
Log.d(Config.LOGTAG, "Clicked annotation is : " + text);
}
}
};
use this code to set cursor at the end
editText.setSelection(editText.getText().length());

Creating new Textviews in another activity based onClick android

I would like to create a new textview to hold the information sent each time the button is clicked. I have the data I want passing to another screen in a textview but each time i try to put new data it overrides this data because it uses the same textView (textview4). I would like to know if there is a way of creating a new text view to hold my data each time the button is clicked. I hope I was clear enough, thanks.
This code is from a class called CreateWorkout.Java
public void createNewWorkout (View view){
TextView Exercise1TextView = (TextView) findViewById(R.id.Exercise1TextView);
EditText weightEntered = (EditText)findViewById(R.id.WeightLiftedEditText);
EditText reps = (EditText)findViewById(R.id.RepsEditText1);
EditText sets = (EditText)findViewById(R.id.setsEditText1);
Intent getWorkoutIntent = new Intent(this, SelectWorkout.class);
getWorkoutIntent.putExtra("Workout", Exercise1TextView.getText().toString()
+ " " + weightEntered.getText().toString() + "kg"
+ " " + reps.getText().toString() + " reps"
+ " " + sets.getText().toString() + " sets");
startActivity(getWorkoutIntent);
}
This is where the intent is called. This is from SelectWorkout.Java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.select_workout);
TextView textView4 = (TextView) findViewById(R.id.textView4);
textView4.setText(getIntent().getExtras().getString("Workout"));
}
i want to take the data entered here to the next screen. So the exercise name(Leg Press), weight(50), set(3), reps(10)
creating a new text view to hold my data each time
Not an exact answer, but this should guide you in the right direction. You could do something like the following:
Get your bundle
Iterate bundle
Create Textviews during iteration and add them to "your_main_layout" which is the id of the main layout inside select_workout
The bundle is the extra data you're sending over from the Intent. The Iterate is going through each item you sent over to this new intent, the create part refers to creating a TextView for each item you sent over. I've supplied links to what I found below.
Listing all extras of an Intent
//Get a bundle:
for (String key : bundle.keySet()) {
// This is each value (text) you sent over from the last intent
Object value = bundle.get(key);
//output data to log, so you can see what prints out
Log.d(TAG, String.format("%s %s (%s)", key, value.toString(), value.getClass().getName()));
//adding a textview to a layout called your_main_layout (which can be a linear layout or something)
//with value.toString() as the text
your_main_layout.addView(createATextView(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT, RelativeLayout.ALIGN_PARENT_RIGHT,
value.toString(), 20, 10, 20));
}
How can I add a TextView to a LinearLayout dynamically in Android?
//method to create view:
public TextView createATextView(int layout_widh, int layout_height, int align,
String text, int fontSize, int margin, int padding) {
TextView textView_item_name = new TextView(this);
// LayoutParams layoutParams = new LayoutParams(
// LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
// layoutParams.gravity = Gravity.LEFT;
RelativeLayout.LayoutParams _params = new RelativeLayout.LayoutParams(
layout_widh, layout_height);
_params.setMargins(margin, margin, margin, margin);
_params.addRule(align);
textView_item_name.setLayoutParams(_params);
textView_item_name.setText(text);
textView_item_name.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSize);
textView_item_name.setTextColor(Color.parseColor("#000000"));
// textView1.setBackgroundColor(0xff66ff66); // hex color 0xAARRGGBB
textView_item_name.setPadding(padding, padding, padding, padding);
return textView_item_name;
}

Android : How to get Dynamic EditText values

In my application I'am creating 10 EditText by dynamically. Now I want to give different value in run time and I want to add it to the list. I have assigned EditText object to the String variable like object.getText.toString(). But i cant get any value.I'am a beginner in android. Can anyone help me how to achieve this? Thanks in advance.
for(int i=0;i<=10;i++)
{
requirement = require.get(i);
RelativeLayout rl1 = new RelativeLayout(getActivity());
rl1.addView(req1);
req1estimate_value = new EditText(getActivity());
String value = req1estimate_value.getText().toString();
rl2.addView(req1estimate_value);
}
Try this. You should instantiate relative layout (rl1) at out of for loop, and should add child views with in that, so that all views could belongs to a parent layout. After that for accessing the values of all EditText you can use following:
String viewValue;
ViewGroup rootView = (ViewGroup) rl1;
int count = rootView.getChildCount();
for (int i = 0; i < count; i++) {
View view = rootView.getChildAt(i);
if (view instanceof EditText) {
viewValue = ((EditText) view).getText().toString();
Log.v("Value:: ", i + " " + viewValue);
} else if (view instanceof Spinner) {
viewValue = ((Spinner) view).getSelectedItem()
.toString();
Log.v("Value:: ", i + " " + viewValue);
}
}
Now after getting values you can put on a List or anywhere you want to use.

How to add dynamic layout in existing layout ( Android, JSON )

I have an app in which I am showing data from JSON. I am displaying data in a dynamic textview on the right and left side of the relative layout. Now I want to add this layout in an existing layout so that I can apply an OnClickListener on the textview. Right now I am getting data into a string and then setting that string into static textviews in the left and right side of the layout.
How would it be possible to generate textview dynamically on the basis of number of data I am getting from JSON ?
for (Region object : temp.phonelist.regionList)
{
if (object.getCCInfoShortDesc() != null || !(object.getCCInfoShortDesc().equals(null)))
{
Log.i("nullexception", "nullexception");
holder.tvDescription.setText(object.getCCInfoShortDesc());
holder.tvDescription.setVisibility(View.VISIBLE);
}else {
Log.i("nullexception1", "nullexception1");
holder.tvDescription.setVisibility(View.GONE);
}
leftContent += object.getCCInfoLeft() + ":" + "\n";
rightContent += object.getCCInfoRight() + "\n";
}
Log.i("lefftcontent", leftContent);
Log.i("rightcontent", rightContent);
if (leftContent != null) {
holder.tvData2.setText(leftContent);
holder.tvData2.setVisibility(View.VISIBLE);
}
if (rightContent != null) {
holder.tvData1.setText(rightContent);
holder.tvData1.setVisibility(View.VISIBLE);
}
You can do it in this way..
final int Count = < Number of TextViews>; // total number of textviews to add
final TextView[] TextViewsARR = new TextView[N]; // create an empty array;
for (int i = 0; i < Count; i++) {
// create a new textview
final TextView rowTextView = new TextView(this);
// set some properties of rowTextView or something
rowTextView.setText("This is row #" + i);
// add the textview to the linearlayout
myLinearLayout.addView(rowTextView);
// save a reference to the textview for later
TextViewsARR [i] = rowTextView;
}
I have a sample below that generates a checkbox dynamically, If you
observe i am generating the checkbox based on the cursor count.
You can adapt this saple to your needs
Instead of checkbox use a texview
Give any layout like linear, relative etc and generate views
dynamically
private CheckBox chkBoxMealType[] = null;
mCursor = db.rawQuery("SELECT meal_type_id,meal_type_name FROM meal_type_mas", null);
if(mCursor.moveToFirst()){
do{
if(chkBoxMealTypeCnt==0){
chkBoxMealType=new CheckBox[mCursor.getCount()];
}
//create a general view for checkbox
chkBoxMealType[chkBoxMealTypeCnt]= new CheckBox(getActivity());
//Create params for veg-checkbox
//Reason:: we don't need to worry about the data exist in cuisine_type_mas table
chkBoxMealType[chkBoxMealTypeCnt].setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
chkBoxMealType[chkBoxMealTypeCnt].setTextColor(getResources().getColor(R.color.searchGoldLight));
chkBoxMealType[chkBoxMealTypeCnt].setTextSize(TypedValue.COMPLEX_UNIT_SP,12);
chkBoxMealType[chkBoxMealTypeCnt].setTag(mCursor.getString(mCursor.getColumnIndexOrThrow(meal_type_mas.COLUMN_MEAL_TYPE_ID)));
chkBoxMealType[chkBoxMealTypeCnt].setText(WordUtils.capitalizeFully(mCursor.getString(mCursor.getColumnIndexOrThrow(meal_type_mas.COLUMN_MEAL_TYPE_NAME))));
mealTypeContainer.addView(chkBoxMealType[chkBoxMealTypeCnt]);
//since cursor count starts from 0 last count must be allowed
chkBoxMealTypeCnt++;
}while(mCursor.moveToNext());
Log.d("", "");
}
I have another sample..... Download this project(Click Here) and run in your editor
Snapshot::
Firstly you need to add a View in your layout ... Like you may try using LinearLayout or HorizontalLayout ... and then attach/add your dynamic textview to that layout.
Pragmatically you may try like this
packageButtons = new ArrayList<TextView>(); // Create your textview arraylist like this
for(int a = 0; a < your_text_view_from_json.size(); a++){
final TextView rowTextView;
rowTextView = new TextView(getApplicationContext());
rowTextView.setText(taxi_type_spin.get(a).taxi_type);
rowTextView.setTextSize(15);
rowTextView.setTextColor(getResources().getColor(R.color.white));
LinearLayout.LayoutParams lparam = new LinearLayout.LayoutParams(0,
LinearLayout.LayoutParams.WRAP_CONTENT, 1);
//rowTextView.setPadding(0, 0, 0, 0);
packageButtons.add(rowTextView);
rowTextView.setLayoutParams(lparam);
rowTextView.setId(a);
final int b = a;
// get value of clicked item over here ..
rowTextView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Button btn = (Button)v;
String get_value = btn.getText().toString();
//Toast.makeText(getApplicationContext(), "Button name is : " + get_value + " AND ID IS : " + rowTextView.getId(), Toast.LENGTH_LONG).show();
if(taxi_type_spin.get(b).taxi_type.equalsIgnoreCase(Utils.Hourly_Package))
{
setTaxiType(rowTextView.getId(),true);
ll_spin.setVisibility(View.VISIBLE);
}
else
{
setTaxiType(rowTextView.getId(),false);
ll_spin.setVisibility(View.GONE);
}
setSelectedButtonColor(b);
}
});
// add the textview to the linearlayout
myLinearLayout.addView(rowTextView);
NOTE rowTextView .. this is your default view attached to your XML file
Hope it helps!
private void setLayout(LinearLayout llayout,
final ArrayList<String> items) {
for (int i = 0; i < items.size(); i++) {
LinearLayout row = null;
LayoutInflater li = getLayoutInflater();
row = (LinearLayout) li.inflate(R.layout.custom_item,
null);
ImageView image = (ImageView) row.findViewById(R.id.image);
llayout.addView(row);
}
}
I would suggest you to use ArrayList, because the class java.util.ArrayList provides resizable-array, which means that items can be added and removed from the list dynamically.
and get value from ArrayList something like this:
for(int i=0; i<arrayList.size(); i++)
{
textName.setText(object.getName());
}
How it is possible to genrate textview dynamically
on the basis of number of data i am getting from json.
You need to create TextView and add it to the parent layout each time you iterate on the forloop. So you will have textView for each of the element of the temp.phonelist.regionList
sample:
for (Region object : temp.phonelist.regionList)
{
TextView tx = new TextView(context); //creating a new instance if textview
//yourstuff goes here
tx.setText(text_you_want);
yourView.addView(tx); //this is to add the textView on each iteration
}
here is your solution do this way,Take one Layout(Linear or Relative) and add control dynamically....
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
for (int i = 0; i < 4; i++)
{
TextView txtDemo = new TextView(getActivity());
txtDemo .setTextSize(16);
txtDemo .setLayoutParams(lp);
txtDemo .setId(i);
lp.setMargins(0, 10, 0, 0);
txtDemo .setPadding(20, 10, 10, 10);
txtDemo .setText("Text View"+ i);
linearlayout.addView(txtDemo );
}
}

Building xml relative layout programmatically

I'm trying to update/populate xml on run-time. The textViews are displayed fine but it seems like it fails position them correctly after the first item (see the else statement). Is it because getId() is not recognised or am I totally wrong?
for(int x=1; x<13; x++){
String prompt="PROMPT_"+String.valueOf(x);
String promptValue = myTacorCursor.getString(myTacorCursor.getColumnIndex(prompt));
//if not empty draw a row
if (!promptValue.equals("")){
//insert new rows into layout
RelativeLayout myLayout = (RelativeLayout) findViewById(R.id.RelativeLayout1);
TextView promptLabel = new TextView(this);
promptLabel.setTextAppearance(this, android.R.style.TextAppearance_DeviceDefault_Large);
promptLabel.setText(myTacorCursor.getString(myTacorCursor.getColumnIndex("PROMPT_"+String.valueOf(x))));
promptLabel.setId(1);
((RelativeLayout) myLayout).addView(promptLabel);
RelativeLayout.LayoutParams mLayoutParams1=(RelativeLayout.LayoutParams)promptLabel.getLayoutParams();
mLayoutParams1.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
if (i==1){
mLayoutParams1.addRule(RelativeLayout.BELOW,R.id.textView7);
Log.w("ID is:", String.valueOf(promptLabel.getId()));
} else{
mLayoutParams1.addRule(RelativeLayout.BELOW,promptLabel.getId());
Log.w("ID is:", String.valueOf(promptLabel.getId()));
}
i++;
}
}
I'm trying to display:
(textView)LABEL xx R.id.textview7
<-- here would be the inserted columns -->
(text view) prompt 1
(text view) prompt 2
(text view) prompt 3
... etc ...'
Setting ids dynamically is OK. Just some more attentiveness and your code works.
As far as you're in the for loop, it's better to increment index only in one place.
After you've changed the LayoutParams of the View you need to set it back: promptLabel.setLayoutParams(layoutParams)
Try this. It should work:
public class MainActivity extends Activity {
private static final int BASE_ID = 1;
private static final int ITEMS_COUNT = 13;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout rootLayout = (RelativeLayout) findViewById(R.id.root);
for (int index = BASE_ID; index < ITEMS_COUNT; index++) {
String prompt = "PROMPT_" + String.valueOf(index);
// if not empty draw a row
// insert new rows into layout
TextView promptLabel = new TextView(this);
promptLabel.setTextAppearance(this,
android.R.style.TextAppearance_DeviceDefault_Large);
promptLabel.setText(prompt);
promptLabel.setId(index);
rootLayout.addView(promptLabel);
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) promptLabel
.getLayoutParams();
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
if (index == BASE_ID) {
layoutParams.addRule(RelativeLayout.BELOW, R.id.top);
Log.d("ID is:", String.valueOf(index));
} else {
layoutParams.addRule(RelativeLayout.BELOW, index - 1);
Log.d("ID is:", String.valueOf(index - 1));
}
promptLabel.setLayoutParams(layoutParams);
}
}
}
You don't need to construct the whole layout programatically. Define it in separate layout xml file and then use layout inflater to inflate it. After that add it where you want it.
I have never seen ids assigned programatically, but with my suggestion you can define them in the xml as usual.
PS: Here is a good example explaining how to use LayoutInflater.

Categories

Resources