I have found a couple ways to do this, but my issue is that my code has to be a LinearLayout with a horizontal orientation. So what happens is the dynamically created TextViews go off the screen.
The code I have is below:
mProductAttrLayout.setOrientation(LinearLayout.HORIZONTAL);
mProductAttrLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
for (ProductAttribute productAttribute : aProductAttributes) {
String name = productAttribute.getName();
TextView attr = new TextView(getContext());
attr.setText(name);
attr.setPadding(8, 8, 8, 8);
attr.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
attr.setTextColor(getResources().getColor(R.color.black));
mProductAttrLayout.addView(attr);
for (int i = 0; i < productAttribute.getValues().size(); i++) {
TextView value = new TextView(getContext());
value.setText(productAttribute.getValues().get(i));
value.setTextColor(getResources().getColor(R.color.black));
value.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
value.setPadding(8, 8, 8, 8);
mProductAttrLayout.addView(value);
}
}
What I currently have is:
| name: value, value, value, val--|
what I need is something like:
name: value, value(unknown number of values)
but I need it to go the the next line in the screen if it's too wide like below:
| name: value, value, value,---|
| value, value, value. ------------|
Hope you can understand what I need?
LinearLayout is the wrong choice here.
You could either write your own layout or use existing work.
What you probably want is usually called a FlowLayout, like this.
Custom layouts can be used like any other Layout. E.g. you can add views with layout.addView. Noramlly the only difference in use is reflected in the custom layoutParams.
Create a flow layout in OnCreate:-
muscle_gp_tag_flow_layout = new FlowLayout(mContext);
//add the flow layout to your main layout
Call the method first time and whenever you want to refresh the view:-
public void createShowSpannableStringMuscleGroup(List<MuscleGroup> muscleGroups) {
// clears the flowlayout views
muscle_gp_tag_flow_layout.removeAllViews();
for (int countGroup = 0; countGroup < muscleGroups.size(); countGroup++) {
MuscleGroup group = muscleGroups.get(countGroup);
if (group.getName() != null && group.getName().length() > 0) {
// inflating the textview views in flow layout
TextView textView=new textView(context);
//set color, background for textview
textView.setText(group.getName().toString());
// adding views to flowlayout muscle group
muscle_gp_tag_flow_layout.addView(mView);
}
}
You have to go with Creating a Customized LinearLayout class. Refer the link for some sample ideas.
How can I add a TextView to a LinearLayout dynamically in Android?
you can use SpannableStringBuilder and TextAppearanceSpan. Example code:
List<String> manyStrings = Arrays.asList(new String[]{"name", "value", "value", "value"});
TextView textView = (TextView) view.findViewById(R.id.textView);
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
for (int i = 0; i < manyStrings.size(); i++) {
String text;
if (i == 0) {
text = manyStrings.get(i) + ": ";
} else if (i == manyStrings.size() - 1) {
text = manyStrings.get(i);
} else {
text = manyStrings.get(i) + ", ";
}
if (i == 0) {
spannableStringBuilder.append(text);
spannableStringBuilder.setSpan(new TextAppearanceSpan(getActivity(), android.R.style.TextAppearance_DeviceDefault_Large), 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
int oldLength = spannableStringBuilder.length();
spannableStringBuilder.append(text);
spannableStringBuilder.setSpan(new TextAppearanceSpan(getActivity(), android.R.style.TextAppearance_DeviceDefault_Small), oldLength, spannableStringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
textView.setText(spannableStringBuilder);
Read more about SpannableStringBuilder and TextAppearanceSpan:
http://developer.android.com/reference/android/text/SpannableStringBuilder.html
http://developer.android.com/reference/android/text/style/TextAppearanceSpan.html
I know this is an old question I asked long ago but they (Google) have given us a solution to this problem using FlexboxLayout with the flexWrap="wrap" attribute.
This is for anyone else that finds this question with the same problem.
Example in XML:
<com.google.android.flexbox.FlexboxLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:flexWrap="wrap" />
For more info you can visit the github repo here FlexboxLayout Repo
It works like this:
Can read more over here:
Build flexible layouts with FlexboxLayout
Related
Is it possible to make part of the text inside EditText one color and the other part another color?
I have an example working with Html, but you can easily change it
String text = "<p>Hello world</p>";
// create Spanned
Spanned spanned = Html.fromHtml(text);
// create SpannableString
SpannableString spanString = new SpannableString(spanned);
// set colored part
ClickableSpan coloredPart = new ClickableSpan() {
#Override
public void onClick(View textView) {
}
#Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
ds.setColor(Color.WHITE);
}
};
spanString.setSpan(coloredPart, 0, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
editText.setText(spanString, TextView.BufferType.SPANNABLE);
Sure no problem.
TextAppearanceSpan mHighlightTextSpan = new TextAppearanceSpan(mContext, R.style.searchTextHighlight);
int startOfTextSearchTeam = orderModel.getTitle() != null ? indexOfSearchTermFromName(orderModel.getTitle()) : -1; //simple search for string in string for index
final SpannableString highlightTitle = new SpannableString(orderModel.getTitle() + " " + mContext.getString(R.string.count_open_bracket) + orderModel.getImageCount() + mContext.getString(R.string.count_closed_bracket));
// Sets the span to start at the starting point of the match and end at "length"
// characters beyond the starting point
if(startOfTextSearchTeam != -1){
highlightTitle.setSpan(mHighlightTextSpan, startOfTextSearchTeam, startOfTextSearchTeam + mSearchTerm.length(), 0);
itemViewHolder.txtOrderTitle.setText(highlightTitle);
}
I do this inside a recycler view adapter as I'm highlighting spans on each row as they search, but it's identical concept. Also I knew up the highlightTextSpan only one time in the constructor.
Hope that helps. Goodluck.
You can use SpannableString, try this.
SpannableString spannableText = new SpannableString("Text default to color");
final EditText diffColor = new EditText(getActivity());
// make "Text" (characters 0 to 4) red
spannableText.setSpan(new ForegroundColorSpan(Color.RED), 0, 4, 0);
diffColor.setText(spannableText, TextView.BufferType.SPANNABLE);
try this. It will work...
EditText edtText=(EditText)findViewById(R.id.edtText);
SpannableStringBuilder sb = new SpannableStringBuilder("Hello world in android");
final ForegroundColorSpan fcs = new ForegroundColorSpan(Color.RED);
// code to specify the character which do you want to change color. In this I have set value from 0,4 to change the color of firts 4 character from string.
sb.setSpan(fcs,0,4, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
edtText.setText(sb);
I'm trying to make a Scheduling app, and in doing so have made a Schedule screen with TextViews and Views that represent the time slots that an activity can correspond to.
However I'm having a hard time getting a generated TextView (which will represent the activity on the Schedule) to line up correctly with the View associated with the Activity's start time.
For example in this case I make a TextView with text = "CSI2120", and attempt to line it up with line (which is a View) above the "13:00" TextView here. However I am missing something as the advice from these links as I can't get them to work.
Can I set “android:layout_below” at runtime, programmatically?
Android How to change layout_below to TextView programmatically (See Second Way in the Answer)
The TextView is in the default location on the top-right, not where I want it to be. What should be doing instead of what the links advise?
Here is my full method. timeSlots is an array of R.id.view[####] ints and Schedule is the Activity the method is in:
public void displayDailyActivities(int[] timeSlots){
String[] todaysActivities = {"CSI2120", "01", "14", "2017", "0300", "0400"};
// Make the associated TextView(s)
for(int i=0; i < todaysActivities.length; i=i+6){
int startTime = Integer.valueOf(todaysActivities[i+4]);
int startTimeHour = startTime / 100;
int startTimeMin = startTime % 100;
// Make the TextView and add it to the Schedule
// Code I got from links
TextView newActivity = new TextView(Schedule.this);
RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
LinearLayout.LayoutParams linearParams = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
// Make the activity, grabbing the corresponding timeslot (View) from the timeSlots array
newActivity.setText(todaysActivities[i]);
// In this case ( timeSlots[startTimeHour + 1] ) returns ( R.id.view0300 )
// which is the View (line) on the Schedule directly above to the "03:00" TextView
relativeParams.addRule(RelativeLayout.BELOW, timeSlots[startTimeHour + 1]);
newActivity.setLayoutParams(relativeParams);
linearParams.setMargins(0, startTimeMin-3, 0, 0);
newActivity.setLayoutParams(linearParams);
// Add to the screen
RelativeLayout schedule = (RelativeLayout) findViewById(R.id.scheduleView);
schedule.addView(newActivity);
// Make sure we're not going out of bounds
if(i + 6 > todaysActivities.length){
i = todaysActivities.length;
}
else{
}
}
}
EDIT: The code that I've found from other similar questions, specifically, that doesn't work for me are the lines:
TextView newActivity = new TextView(Schedule.this);
RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
LinearLayout.LayoutParams linearParams = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
...
relativeParams.addRule(RelativeLayout.BELOW, timeSlots[startTimeHour + 1]);
newActivity.setLayoutParams(relativeParams);
linearParams.setMargins(0, startTimeMin-3, 0, 0);
newActivity.setLayoutParams(linearParams);
you are overriding the relativeParams with the linearParams. set margins to relativeParms variable iteself and then setLayoutParams to newActivity like below:
relativeParams.addRule(RelativeLayout.BELOW, timeSlots[startTimeHour + 1]);
relativeParams.setMargins(0, startTimeMin-3, 0, 0);
newActivity.setLayoutParams(relativeParams);
// Add to the screen
RelativeLayout schedule = (RelativeLayout) findViewById(R.id.scheduleView);
schedule.addView(newActivity);
This can solve your problem
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.setMargins(10,10,10,10);
TextView textView = (TextView) findViewById(R.id.textView);
textView.setLayoutParams(params);
I am trying to do a app with multiple EditText and is wondering if there is any easy way to do that.
For instance to add matrix of EditText from your java code to your activity_main.xml or maby do a for loop which adds them at your specified location.
EditText[][] edittext = new EditText[10][10];
gridView = (GridView) findViewById(R.id.gridview);
for (int i=0;i<9;i++){
for (int j=0;j<9;j++){
gridView.addView(edittext[i][j], column X, row Y);
}
}
Here is a working example..
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout root = (LinearLayout) findViewById(R.id.master);
EditText t[][] = new EditText[10][10];
LinearLayout.LayoutParams dim = new LinearLayout.LayoutParams(LinearLayout.LayoutParams
.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
for (int i=0;i<9;i++){
for (int j=0;j<9;j++){
t[i][j]=new EditText(this);
t[i][j].setLayoutParams(dim);
t[i][j].setHint("Hello World , EditText[" + i + "]" + "[" + j + "]");
root.addView(t[i][j]);
}
}
}
There is no easier way to make a "form". Each EditText is a different xml component with different id, with its own attributes.
What you can do is an adapter with listview/recyclerview with EditText the holder.
You can do smth like that:
ArrayList<EditText> editTexts = new ArrayList<>();
LinearLayout ll = (LinearLayout) findViewById(R.id.container);
EditText oneOfEditText;
for (int i = 0; i < 100; i++){
oneOfEditText = new EditText(this);
oneOfEditText.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
));
oneOfEditText.setHint("MyHint");
oneOfEditText.setId(i);
ll.addView(oneOfEditText);
editTexts.add(oneOfEditText);
}
And then you can access these EditTexts like that:
for (EditText editText : editTexts){
Log.d("myLog", editText.getText().toString());
}
But the best practice for such things is to create them statically in xml, and then you can access them either via static ids, or like that:
for (int i =0; i < ll.getChildCount(); i++){
editTexts.add((EditText) ll.getChildAt(i));
}
I think the proper way implement each item is to use an adapter. In your case, you can use SimpleAdapter or create a custom adapter that extends BaseAdapter and set it using setAdapter(ListAdapter).
You can check the documentation for GridView here:
http://developer.android.com/guide/topics/ui/layout/gridview.html
I try to add dinamically some TextViews in Java. I assume that when I want to use setText() method, I should earlier connect my Java's TextView object with XML's TextView - I use setId().
At the end, I got NullPointerException in the line where I use setId().
My code:
TextView[] tvQuestion = new TextView[numberOfQuestions];
TextView[] tvAnswer1 = new TextView[numberOfQuestions];
TextView[] tvAnswer2 = new TextView[numberOfQuestions];
TextView[] tvAnswer3 = new TextView[numberOfQuestions];
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
for (int i = 0; i < numberOfQuestions; i++) {
tvQuestion[i].setId(View.generateViewId()); // NullPointerException!
tvAnswer1[i].setId(View.generateViewId());
tvAnswer2[i].setId(View.generateViewId());
tvAnswer3[i].setId(View.generateViewId());
tvQuestion[i].setLayoutParams(params);
tvAnswer1[i].setLayoutParams(params);
tvAnswer2[i].setLayoutParams(params);
tvAnswer3[i].setLayoutParams(params);
tvQuestion[i].setText(question[i]);
tvAnswer1[i].setText(option1[i]);
tvAnswer2[i].setText(option2[i]);
tvAnswer3[i].setText(option3[i]);
layAll.addView(tvQuestion[i]);
layAll.addView(tvAnswer1[i]);
layAll.addView(tvAnswer2[i]);
layAll.addView(tvAnswer3[i]);
}
EDIT:
Solution: Philipp Jahoda's post.
You just created an Array for the TextViews. The TextViews inside the Array are null as long as they are not initialized.
So you need to call
tvQuestion[i] = new TextView(Context);
tvAnswer[i] = new TextView(Context);
// and so on ...
// and then later
tvQuestion[i].setId(View.generateViewId());
// and so on ...
before setting the ID and other stuff.
So, I want to create a custom Android TextView with a border INSIDE AN XML FILE, so not programmatically, and create 10 of those using a for-loop. Something like this:
LinearLayout layout = new LinearLayout(//something, //something);
TextView tv;
String[] data = //Certain data which I'm getting
for(int i = 0; i < data.length; i++) {
tv = (TextView) findViewById(R.id.tvTest);
layout.addView(tv);
}
But this doesn't work for me for some reason. So to summarize:
> Create custom TextView in XML (NOT PROGRAMMATICALLY with Java, but in XML)
> Create an x amount of this particular TextView
> Add it to the screen in Java
Can you help me with this?
This is code snippet
LayoutInflater inflater = (LayoutInflater) _context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for ( ) {
View listItemView = inflater.inflate(R.layout.detaillistitem, _ListLayout, false);
_ListLayout.addView(listItemView);
TextView descriptionText = (TextView) listItemView.findViewById(R.id.Text1);
descriptionText.setText("");
}
R.layout.detaillistitem is item u want to inflate.
_ListLayout is LinearLayout to which you can add above item.
Try like this..
Create your textview in an external layout file..
for(int i = 0; i < data.length; i++) {
View v = LayoutInflater.from(this).inflate(R.layout.textview, null);//R.layout.textview is your textview id you want to repeat..
layout.addView(v);
}