<ScrollView
android:id="#+id/scrollView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#id/btnAddRow"
android:layout_below="#id/llInventoryViewHeader"
android:isScrollContainer="true"
android:scrollbars="vertical" >
<LinearLayout
android:id="#+id/llDynamicView"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
</LinearLayout>
</ScrollView>
Code which set rows in linear layout :-
/**
* Set Edit text
*/
private void setUsedList() {
for (final InventoryResource inventoryResource : mCurrentUsedResourceList) {
final LinearLayout LL = new LinearLayout(InventoryActivity.this);
LL.setOrientation(LinearLayout.HORIZONTAL);
final LayoutParams LLParams = new LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
LL.setWeightSum(10f);
LL.setLayoutParams(LLParams);
// ResourceName Params
final LinearLayout.LayoutParams resourceViewParams = new LinearLayout.LayoutParams(
0, LinearLayout.LayoutParams.WRAP_CONTENT);
resourceViewParams.weight = 6f;
resourceViewParams.setMargins(5, 5, 5, 5);
// Resource Edittext
final EditText edtTextResourceName = new EditText(
InventoryActivity.this);
edtTextResourceName.setGravity(Gravity.CENTER);
edtTextResourceName.setLayoutParams(resourceViewParams);
edtTextResourceName.setInputType(InputType.TYPE_CLASS_TEXT);
edtTextResourceName.setTextColor(Color.BLACK);
edtTextResourceName.setTextSize(16f);
edtTextResourceName.setBackground(getResources().getDrawable(
R.drawable.box_edt_values));
// Amount Params
final LinearLayout.LayoutParams amtViewParams = new LinearLayout.LayoutParams(
0, LinearLayout.LayoutParams.WRAP_CONTENT);
amtViewParams.weight = 2f;
amtViewParams.setMargins(5, 5, 5, 5);
final EditText edtTextConstructorAmt = new EditText(
InventoryActivity.this);
edtTextConstructorAmt.setGravity(Gravity.CENTER);
edtTextConstructorAmt.setInputType(InputType.TYPE_CLASS_PHONE);
edtTextConstructorAmt.setLayoutParams(amtViewParams);
edtTextConstructorAmt.setTextColor(Color.BLACK);
edtTextConstructorAmt.setTextSize(16f);
edtTextConstructorAmt.setBackground(getResources().getDrawable(
R.drawable.box_edt_values));
final EditText edtTextInspectorAmt = new EditText(
InventoryActivity.this);
edtTextInspectorAmt.setInputType(InputType.TYPE_CLASS_PHONE);
edtTextInspectorAmt.setGravity(Gravity.CENTER);
edtTextInspectorAmt.setLayoutParams(amtViewParams);
edtTextInspectorAmt.setTextColor(Color.BLACK);
edtTextInspectorAmt.setTextSize(16f);
edtTextInspectorAmt.setBackground(getResources().getDrawable(
R.drawable.box_edt_values));
final InventoryPojo pojo = new InventoryPojo();
pojo.id = inventoryResource.getOrderNum();
mOrderNumber += 1;
pojo.edtResourceName = edtTextResourceName;
pojo.edtConstructoreAmt = edtTextConstructorAmt;
pojo.edtInspectoreAmt = edtTextInspectorAmt;
mUsedList.add(pojo);
if (mPreference.getString(Preferences.LAN_CULTURE,
Constants.CULTURE_HEBREW).equalsIgnoreCase(
Constants.CULTURE_ENGLISH)) {
LL.addView(edtTextResourceName);
LL.addView(edtTextConstructorAmt);
LL.addView(edtTextInspectorAmt);
mLLDetails.addView(LL);
mLLDetails.invalidate();
} else {
LL.addView(edtTextInspectorAmt);
LL.addView(edtTextConstructorAmt);
LL.addView(edtTextResourceName);
mLLDetails.addView(LL);
mLLDetails.invalidate();
}
}
}
Code :-
parent = (RelativeLayout)findViewById(R.id.rlParent);
parent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener(){
public void onGlobalLayout(){
int heightDiff = parent.getRootView().getHeight()- parent.getHeight();
// IF height diff is more then 150, consider keyboard as visible.
if(heightDiff > 150){
// Its keyboard mostly
parent.setPadding(0, 0, 0, heightDiff);
}
else if(heightDiff < 150){
// Keyboard goes away, readjust
parent.setPadding(0, 0, 0, 0);
}
}
});
I am having scroll view inside which dynamically rows are being added. The problem i am facing is that if my view is having 10 rows then when i start typing it won't scroll upto end. For e.g. in case of 10 rows I am able to scroll up to 7 row and then other 3 rows are not visible and have to close the keyboard by pressing back and then i can add the value to rest 3 row.
I have added inputMode to adjustPan in my manifest for the activity and also added android:isScrollContainer="true" but still its not working.
Anyone having any idea how to resolve it.
Okay, try this it might save your cause,
first in your main XML which holds this Scroll view give identefier to its root i.e its parent
Second, android does provide you an API which tell you about dimensions of its view which are assigned to them right before they are drawn, this you can read through ViewTreeObservers
use this code to check when keyboard is inflated, when its inflated, you can assign the height differece as padding bottom to your parent view, and when keyboard goes away just reset the padding set. this will make sure you can scroll all view which are hidden beneath inflated keyboad.
parent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener(){
public void onGlobalLayout(){
int heightDiff = parent.getRootView().getHeight()- parent.getHeight();
// IF height diff is more then 150, consider keyboard as visible.
if(heightDiff > 150){
// Its keyboard mostly
parent.setPadding(0, 0, 0, heightDiff);
}
else if(heightDiff < 150){
// Keyboard goes away, readjust
parent.setPadding(0, 0, 0, 0);
}
}
});
4 make sure you have this parameter defined in you activity in manifiest file
android:windowSoftInputMode="adjustResize"
You might want to play around with the windowSoftInputMode. And here's an interesting discussion that helped me solve my similar problem.
Hope this helps you!
Your scrollview seems to be fine.
For doing scroll you just have to add single line inside your activity of manifiest file.
android:windowSoftInputMode="adjustResize"
Related
Click here to see the image
In the profile page of my application, I want to have an interest section as shown in the image. The user has a list of interest under his profile. I want to show his/her interests inside a horizontal LinearLayout. I have created an array of TextViews and add them dynamically inside the parent LinearLayout, but I do not want to add the TextViews when there is no more space. Instead, I want to add a TextView showing the number of remaining interests.
As shown in the picture (use the image link), the user had 24 interests, 4 of them fit horizontally on the same line and last TextView(+20) shows the number of remaining interests on the same line.
String interestList[]={"Travel","Music","Photography","Sports","Dance","Animals","SciFi Movies"};
int interestWidth =0, parentWidth=interestLinearLayout.getWidth();
for(String interest: interestList) {
TextView textView = new TextView(MainActivity.this);
textView.setBackground(getResources().getDrawable(R.drawable.interests_bg));
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(2,0,10,2);
textView.setLayoutParams(params);
textView.setPadding(2, 2, 2, 2);
textView.setText(" "+interest+" ");
textView.setTextColor(getResources().getColor(R.color.white));
textView.setIncludeFontPadding(true);
interestWidth += textView.getWidth();
if(interestWidth<parentWidth) //both are 0 on first iteration of loop???
interestLinearLayout.addView(textView);
else
break;
}
You can add views dynamically but first you need a reference to the parent view to which you want to add a view.
You can do this by just using findViewById. Assuming it's a linear layout,
LinearLayout parent = findViewById(R.id.parent);
// Then create a textview
TextView textView = new TextView(this);
// Add the view to the parent
parent.addView(textView);
And that's it! To change properties about the TextView, you can use TextView getters and setters. If you want to change the margin, padding or height of width of the TextView, use LayoutParams
// Remember that I'm using LinearLayout.LayoutParams because the parent of the ttextview is a LinearLayout
LinearLayout.LayourParams params = textView.getLayoutParams();
// Remember these values are in pixels
params.height = 100;
params.width = 200;
There are tons of problems using this method, such as setting height and width in pixels instead of dps. And writing a lot of code when you could have done it in xml. You can however make this much easier by creating an xml file in your res/layout and then inflating it and finally adding it to the parent.
You can do this by -
// First get the layout inflater
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
TextView textView = inflater.inflate(R.layout.myTextView, null);
linearLayout.addView(textView);
Finally addressing your problem about adding only enough views that the linearLayout doesn't go beyond the screen width.
The easiest solution is, to loop through the interest list and in every iteration of the loop, measure the combined width of the TextViews created and then checking whether it exceeds the width of the linearLayout.
It would look similar to this -
int combinedWidth = 0;
int linearLayoutWidth = linearLayout.getMeasuredWidth();
for(String interest : interests){
TextView view = inflater.inflate(R.layout.textview, null);
combinedWidth += textView.getMeasuredWidth();
view.setText(interest);
if(combinedWidth > linearLayoutWidth){
// No need to add more views
break;
}else{
linearLayout.addView(textView);
}
}
However, the above solution may or may not work depending on when it is executed. So post the activity code along with the xml file so that I can better answer your question.
The interestWidth and parentWidth are initially 0 because they have not been laid out when getWidth is called.
get width for dynamically created textViews
The above link helped me getting width of dynamically created textViews from interestList.
And by using ViewTreeObserver on interestLinearLayout I was able to get the width of LinearLayout after it was laid out.
Finally, the above code should be modified as below to add textViews from JAVA inside a LinearLayout.
final LinearLayout interestLinearLayout = findViewById(R.id.interests);
interestLinearLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
interestLinearLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
String interestList[]={"Travel","Music","Photography","Sports","Dance","Animals","SciFi Movies"};
int interestWidth =0;
int parentWidth = interestLinearLayout.getWidth(); // got width inside view tree observer for linearlayout
for(String interest: interestList) {
TextView textView = new TextView(MainActivity.this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(2,0,10,2);
textView.setLayoutParams(params);
textView.setPadding(2, 2, 2, 2);
textView.setText(interest);
textView.setIncludeFontPadding(true);
textView.measure(0,0); //using approach mentioned in link to get width of text views
interestWidth += textView.getMeasuredWidth();
if(interestWidth<parentWidth)
interestLinearLayout.addView(textView);
else
break;
}
}
});
To create a LinearLayout,
LinearLayout layout = new LinearLayout(MainActivity.this);
To set background color of a layout,
layout.setBackgroundColor(Color.parseColor("#135517"));
To set width and height of the layout,
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams
(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params.setMargins(15, 5, 5, 5);
layout.setLayoutParams(params);
The orientation,
layout.setOrientation(LinearLayout.HORIZONTAL);
layout.setHorizontalGravity(Gravity.CENTER_HORIZONTAL);
layout.setPadding(10, 10, 5, 5);
Then create a textview,
TextView textView = new TextView(this);
textView.setLayoutParams(params);
textView.setPadding(2, 2, 2, 2);
textView.setText(" "your" ");
textView.setTextColor(getResources().getColor(R.color.white));
textView.setIncludeFontPadding(true);
Add the view to the parent,
layout.addView(textView);
I am killing myself with this problem so I am in desperate need of help.
I have a fragment with custom layout which is populated programmatically with linear layout which consists of an imageview and a textview.
User can dynamically change size of the fragment and here lies the problem.
I have onLayoutChange listener set on the fragment view where i change the size of the textview in respect to the size of the container and everything is correctly set when the container size changes but the views don't redraw themself and after the change all that i can see are the old views with their old width and height as if new width and height have never been applied.
I tried to invalidate the textview and i tried to call requestlayout on the parent view to no avail.
Its as if the new views are set but the old ones are shown.
Heres the code:
private void GenerateViews(View view) {
for (final Item artikl : listaArtikala) {
LinearLayout l_artikl = new LinearLayout(getActivity());
l_artikl.setPadding(10, 5, 0, 5);
final ImageView img = new ImageView(getActivity());
img.setMinimumWidth(image_width);
img.setMinimumHeight(image_height);
img.setScaleType(ScaleType.FIT_CENTER);
l_artikl.addView(img);
final TextView txv = new TextView(getActivity());
// dummy if to trigger after container size changes.
if(txv_artikl_width > 265)
txv.setWidth(300);
else
txv.setWidth(100);
txv.setWidth(300);
txv.setHeight(txv_artikl_height);
txv.setText(artikl.getName());
txv.setTextSize(15);
txv.setClickable(true);
txv.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
txv.setBackgroundColor(getResources().getColor(
R.color.LightSteelBlue));
txv.setPadding(5, 0, 10, 5);
l_artikl.addView(txv);
((ViewGroup) view).addView(l_artikl);
}
view.requestLayout();
}
All the help is appreciated.
After your if statement you reset the width of your textview:
if(txv_artikl_width > 265)
txv.setWidth(300);
else
txv.setWidth(100);
txv.setWidth(300);
You probably don't want to do that, right?
I am getting list of phone companies from web service and i have to set it to textview but the problem is i am not getting alignment as above image.How to achieve it.
From what I understand, you want to add text views one beside the other, but when they overflow (go out of the screen) the next text view should be placed in the next line.
Doing this is not trivial. Implementing something like this (optimally and correctly) requires understanding of how android draws views (onMeasure and onLayout). However if you do not care about efficiency that much (mainly because you are going to do it only for a small portion of the view) then here is my quick hack:
mContainer = (RelativeLayout) findViewById(R.id.container);
// first layout all the text views in a relative layout without any params set.
// this will let the system draw them independent of one another and calculate the
// width of each text view for us.
for (int i = 0; i < 10; i++) {
TextView tv = new TextView(getApplicationContext());
tv.setText("Text View " + i);
tv.setId(i+1);
tv.setPadding(10, 10, 20, 10);
mContainer.addView(tv);
}
// post a runnable on the layout which will do the layout again, but this time
// using the width of the individual text views, it will place them in correct position.
mContainer.post(new Runnable() {
#Override
public void run() {
int totalWidth = mContainer.getWidth();
// loop through each text view, and set its layout params
for (int i = 0; i < 10; i++) {
View child = mContainer.getChildAt(i);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
// this text view can fit in the same row so lets place it relative to the previous one.
if(child.getWidth() < totalWidth) {
if(i > 0) { // i == 0 is in correct position
params.addRule(RelativeLayout.RIGHT_OF, mContainer.getChildAt(i-1).getId());
params.addRule(RelativeLayout.ALIGN_BOTTOM, mContainer.getChildAt(i-1).getId());
}
}
else {
// place it in the next row.
totalWidth = mContainer.getWidth();
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
params.addRule(RelativeLayout.BELOW, mContainer.getChildAt(i-1).getId());
}
child.setLayoutParams(params);
totalWidth = totalWidth - child.getWidth();
}
mContainer.requestLayout();
}
});
Basically, I let the system do the layout and measurement for me in the first round(s) of drawing. Then using the widths of each text view now available, I reset the layout params based on the wrapping logic and do the layout again.
Try it with text of different size, it will auto adjust. I would say this solution is pretty hacky but it works. If you are not satisfied with it take a look at this.
use
android:textAlignment="textStart"
I have added a button and an edittext onto a framelayout. The problem is I appear to lose the functionality of being able to click the button. When I click the button, the keyboard appears for the edittext. How can I add button/editext objects into a layout so that they appear on a new row and do not affect each other. I was using the padding option to move them about, but this still causes the button to be non-clickable.
Here is my code: -
FrameLayout reportLayout = (FrameLayout) findViewById(R.id.reportDetailLayout);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
Button executeButton = new Button(this);
executeButton.setClickable(true);
executeButton.setOnClickListener(handleOnClick(executeButton));
EditText text1 = new EditText(this);
executeButton.setText("Execute");
executeButton.setMinimumHeight(10);
executeButton.setMinimumWidth(150);
text1.setId(1);
text1.setHint("Enter Value");
executeButton.setPadding(0, 0, 0, 0);
text1.setPadding(12, 70, 0, 0);
executeButton.setLayoutParams(params);
text1.setLayoutParams(params);
reportLayout.addView(executeButton);
reportLayout.addView(text1);
FrameLayout will cause Views to overlap. Try LinearLayout with setOrientation().
And you don't use padding for placement. Padding is not same thing as a margin.
I have a form with several Views on it, the last one is a Spinner that is bound to an adapter to get it's data from a Web Server via a POST request, at the end I append an additional entry for "Other...". If this option is selected on the spinner, a new EditText View at the bottom where the user enters a custom value, I've managed to get the EditText View to show on the screen, but it's positioned at the very top, over my other Views and I can't seem to find the way to make it appear at the bottom, below the Spinner as I want it to, here is the code I have so far:
EditText suggestCarrierField = new EditText(getBaseContext());
suggestCarrierField.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
suggestCarrierField.setHint("Suggest your carrier");
((AbsoluteLayout) findViewById(R.id.createAccountView)).addView(suggestCarrierField);
((AbsoluteLayout) findViewById(R.id.createAccountView)).invalidate();
Using an AbsoluteLayout, you need to use AbsoluteLayout.LayoutParams, rather than ViewGroup.LayoutParams.
int width = 100, height = 25, x = 0, y = 200;
AbsoluteLayout.LayoutParams lp = new AbsoluteLayout.LayoutParams(width, height, x, y);
suggestCarrierField.setLayoutParams(lp);
Having said that, I strongly urge you to consider implementing this with a RelativeLayout (or LinearLayout) instead... AbsoluteLayout is deprecated, and for very good reason. There are so many different Android devices with different sized screens now, AbsoluteLayout just won't work across them all.
When setting the LayoutParams for suggestCarrierField, don't use ViewGroup but instead use AbsoluteLayout.LayoutParams. It has a constructor which takes a height, width AND x and y coordinates. See the AbsoluteLayout.LayoutParams doc . Here is a quick app I whipped which demos this:
public class AbsoluteLayoutTest extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AbsoluteLayout as = new AbsoluteLayout(this);
TextView tvTop = new TextView(this);
tvTop.setText("top");
tvTop.setLayoutParams(new AbsoluteLayout.LayoutParams(AbsoluteLayout.LayoutParams.FILL_PARENT, AbsoluteLayout.LayoutParams.WRAP_CONTENT, 0, 0));
TextView tvMid = new TextView(this);
tvMid.setText("middle");
tvMid.setLayoutParams(new AbsoluteLayout.LayoutParams(AbsoluteLayout.LayoutParams.FILL_PARENT, AbsoluteLayout.LayoutParams.WRAP_CONTENT, 0, 80));
TextView tvBot = new TextView(this);
tvBot.setText("bottom");
tvBot.setLayoutParams(new AbsoluteLayout.LayoutParams(AbsoluteLayout.LayoutParams.FILL_PARENT, AbsoluteLayout.LayoutParams.WRAP_CONTENT, 0, 180));
as.addView(tvTop);
as.addView(tvMid);
as.addView(tvBot);
setContentView(as);
}
}
This will result in three text views. One at the top (y-coord = 0), one in the middle (y-coord = 80) and one at the bottom (y-coord = 180).