I create a TableLayout dynamically via code and want to set a margin between columns. The only type of content my TableRows contain are TextViews.
My intention was to put a simple android:layout_marginRight on each TextView. But I want to definde this via xml instead of code.
What I tried:
The code:
txtView.setTextAppearance(context, R.style.TableTextView);
txtView.setText(content);
tableRow.addView(txtView);
The XML
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="TableTextView">
<item name="android:textAppearance">?android:attr/textAppearanceLarge</item>
<item name="android:textStyle">bold</item>
<item name="android:layout_marginRight">5dip</item>
</style>
</resources>
What happens:
The layout_marginRight set in the XML does not work, but the textAppearance and textStyle set in the XML do work. I assume the setTextAppearance-method is the wrong way for assigning a margin to a TextView? It would be really nice if I could do this via XML (like I tried it above) instead of Java-code.
Thank you!
This happens because you're setting the style to the text itself and not the TextView element.
You should set the element style in the XML. it's possible to achive this from the code as well, but i think it's best to do that in the XML Layout file.
Something like :
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/mTableTextView" />
About setting that from code, i'm not an expert but i understood you can inflate it somehow.
Check out This, And This questions.
You want to give margin between columns
android.widget.TableRow.LayoutParams param = new android.widget.TableRow.LayoutParams();
param.rightMargin = Converter.dpToPixel(10, getContext()); // right-margin = 10dp
button.setLayoutParams(param);
// Converter:
private static Float scale;
public static int dpToPixel(int dp, Context context) {
if (scale == null)
scale = context.getResources().getDisplayMetrics().density;
return (int) ((float) dp * scale);
}
you can set different of value table parameters.
Related
I have a problem with Android Glide. I am trying to quickly swap my image, they just become all placeholder size, and my placeholder image is very low size. So what I need to do?
Maybe I need to check if it's loaded or something, but I don't know how.
Glide.with(this)
.load(quest.get(id).getImage())
.placeholder(R.drawable.load)
.fitCenter()
.crossFade()
.into(imageView);
According to this issue on Glide GitHub page you can fix it with adding following line to your request of Glide:
.dontAnimate()
That would make your full load line:
Glide.with(context)
.load("http://lorempixel.com/150/150")
.placeholder(R.drawable.no_image)
.override(100, 100)
.dontAnimate()
.into(imageView);
I do it like mentioned below:
The idea is to set the scale type to as required by the place holder initially & attach listener to change the scale type again to as required by the downloaded image after the image is downloaded.
//ivBuilderLogo = Target ImageView
//Set the scale type to as required by your place holder
//ScaleType.CENTER_INSIDE will maintain aspect ration and fit the placeholder inside the image view
holder.ivBuilderLogo.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
//AnimationDrawable is required when you are using transition drawables
//You can directly send resource id to glide if your placeholder is static
//However if you are using GIFs, it is better to create a transition drawable in xml
//& use it as shown in this example
AnimationDrawable animationDrawable;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
animationDrawable=(AnimationDrawable)context.getDrawable(R.drawable.anim_image_placeholder);
else
animationDrawable=(AnimationDrawable)context.getResources().getDrawable(R.drawable.anim_image_placeholder);
animationDrawable.start();
Glide.with(context).load(logo_url)
.placeholder(animationDrawable)
.listener(new RequestListener<String, GlideDrawable>() {
#Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource)
{
return false;
}
//This is invoked when your image is downloaded and is ready
//to be loaded to the image view
#Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource)
{
//This is used to remove the placeholder image from your ImageView
//and load the downloaded image with desired scale-type(FIT_XY in this case)
//Changing the scale type from 'CENTER_INSIDE' to 'FIT_XY'
//will stretch the placeholder for a (very) short duration,
//till the downloaded image is loaded
//setImageResource(0) removes the placeholder from the image-view
//before setting the scale type to FIT_XY and ensures that the UX
//is not spoiled, even for a (very) short duration
holder.ivBuilderLogo.setImageResource(0);
holder.ivBuilderLogo.setScaleType(ImageView.ScaleType.FIT_XY);
return false;
}
})
.into( holder.ivBuilderLogo);
My transition drawable (R.drawable.anim_image_placeholder) :
(not required if using a static image)
<?xml version="1.0" encoding="utf-8"?>
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="#drawable/loading_frame1" android:duration="100" />
<!--<item android:drawable="#drawable/loading_frame2" android:duration="100" />-->
<item android:drawable="#drawable/loading_frame3" android:duration="100" />
<!--<item android:drawable="#drawable/loading_frame4" android:duration="100" />-->
<item android:drawable="#drawable/loading_frame5" android:duration="100" />
<!--<item android:drawable="#drawable/loading_frame6" android:duration="100" />-->
<item android:drawable="#drawable/loading_frame7" android:duration="100" />
<!--<item android:drawable="#drawable/loading_frame8" android:duration="100" />-->
<item android:drawable="#drawable/loading_frame9" android:duration="100" />
<!--<item android:drawable="#drawable/loading_frame10" android:duration="100" />-->
</animation-list>
What I did in this regard was to use override() to enforce image size. If you have a gridview and you need to have two images in each row, this is how you find the screen size in pixels to calculate the correct width and height of the image:
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
placeholderWidth = size.x / 2 ;
placeholderHeight = size.x * 3 / 2 ; // based on the image's height to width ratio
Once the desired width and height for each image is in hand, it's easy to use override:
Glide.with(context)
.load(url)
.placeholder(R.drawable.loading)
.override(placeholderWidth,placeholderHeight)
.into(viewHolder.imageViewHolder);
If I correctly understand your problem, you need to load images, but they must have width and height bigger than your placeholder image.
To solve your problem you first should read documentation for Glide.
I can't see your ImageView definition in the xml file, but i think that you use wrap_content attribute for width and height.
If I am right there is your bottleneck.
Before image loading is started, Glide gets exact ImageView width and height. After that it loads image from the network and at the same time resize it according to the one of the ImageView attributes(width or height).
Thats why you get small images after loading.
To solve your problem just set width or height of the ImageView in value that you expect to see. Other side of the image will be automatically calculated by the Glide logic.
If someone came here from search just like me and wondering how to change Glide's placeholder size but remain image size original (in my case placeholder was to big), here's the solution. Wrap your placeholder drawable in another drawable with tag inset:
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:inset="20%">
<animated-rotate
android:drawable="#drawable/ic_loading"
android:pivotX="50%"
android:pivotY="50%" />
</inset>
Note that you can replace animated-rotate with any of allowed tags. Also, you can set different insets for each side of drawable (insetTop, insetBottom and so on), and specify insets in dp or %
Soft input mode is "SOFT_INPUT_ADJUST_PAN", and when keyboard shown, EditText moves up to stay visible, but the keyboard and txt's bottom are always sticked together as seen on screenshot, I want some space between them, is it possible?
Also input mode must stay as "SOFT_INPUT_ADJUST_PAN".
Sorry form my english, Thanks in Advance...
I applied above methods which worked for me was
Set android:windowSoftInputMode on the Activity to "adjustPan"
than i added the padding to the edittext with gravity bottom
and it works like charm.
Thanks,
May this help you:
If this line is written in your code then remove it:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
OR:
You should not be setting your layout_width and layout_heights with explicit pixel values. Instead, use wrap_parent or fill_parent as appropriate.
OR:
If you have set your minSdkVersion to 3 then change it to minSdkVersion=4
Edit:
Set android:windowSoftInputMode on the Activity to "adjustPan"
OR:
Add this code in your main activity in setOnTouchListener() of your EditText:
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED);
Why don't you try this?
android:windowSoftInputMode="adjustResize"
I know you want to adjust pan but this would solve your problem aswell.
Since you really want to stay with adjustPan, maybe you can try re-designing the XML layout a little bit.
You must also add your required padding to the outer most container element in the layout file.
Simple padding in edit text won't work.
Use drawable with your edit text like below:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="8dp"
android:left="8dp"
android:right="8dp"
android:top="8dp">
<shape android:shape="rectangle">
<corners android:radius="10dp" />
<stroke
android:width="1dp"
android:color="#color/white" />
<solid android:color="#color/transparent" />
</shape>
</item>
</layer-list>
and then use
android:windowSoftInputMode="adjustPan"
in your manifest file.
Just wondering, is your app full screen? does it have the status bar? If it is try to disable full screen mode and try to see if that solves your problem. I remember there was a bug about this some time ago.
try to use GlobalLayoutListener:
private var focusView:View?=null
// Register global layout listener.
decorView?.viewTreeObserver?.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
private val windowVisibleDisplayFrame = Rect()
private var lastVisibleDecorViewHeight: Int = 0
override fun onGlobalLayout() {
// Retrieve visible rectangle inside window.
decorView.getWindowVisibleDisplayFrame(windowVisibleDisplayFrame)
val visibleDecorViewHeight = windowVisibleDisplayFrame.height()
// Decide whether keyboard is visible from changing decor view height.
if (lastVisibleDecorViewHeight != 0) {
if (lastVisibleDecorViewHeight > visibleDecorViewHeight + MIN_KEYBOARD_HEIGHT_PX) {
// Calculate current keyboard height (this includes also navigation bar height when in fullscreen mode).
val currentKeyboardHeight = decorView.height - windowVisibleDisplayFrame.bottom
//keyboardHeight = currentKeyboardHeight
focusView = activity?.currentFocus
focusView.setPadding(0, 0, 0, SET_BOTTOM_PADDING_SPACE) // <---set space here
} else if (lastVisibleDecorViewHeight + MIN_KEYBOARD_HEIGHT_PX < visibleDecorViewHeight) {
focusView.setPadding(0, 0, 0, 0)
}
}
// Save current decor view height for the next call.
lastVisibleDecorViewHeight = visibleDecorViewHeight
}
})
I'm programming an Android app and I'm trying to show a table. My problem is, that the columns don't fill the screen, they just all stick to left.
I already tried using padding, but first I don't think that it's compatible with all display resolutions and second the columns were aligned differently when they had different content in them.
Then I read about weight and this was exactly what I wanted, giving every column a specific percentage of the width of the screen. But weights did lead to the cells sticking to the left again. They did react in no way to the weights I've set.
I program the view in xml templates and inflate them programmatically using the LayoutInflater. Then I add them to the corresponding TableRow. All that works perfectly fine, but they just don't react to the weights.
I would really appreciate your help.
EDIT: The templates refer to a style and look like this:
<?xml version="1.0" encoding="UTF-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/scheduleClass" />
And the style looks like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="scheduleItem" parent="#android:style/TextAppearance.Medium">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:paddingRight">0dp</item>
<item name="android:paddingBottom">10dp</item>
</style>
<style name="scheduleClass" parent="scheduleItem">
<item name="android:layout_weight">0.2</item>
</style>
</resources>
There are other a few other columns, but they just have another name and another weight.
And this is how I add the views to the table:
public void updateList(ArrayList<Lesson> lessons) {
setContentView(R.layout.schedule);
TableLayout table = (TableLayout) findViewById(R.id.table);
for(Lesson cancel : lessons) {
TableRow row = new TableRow(this);
TextView date = (TextView) this.getLayoutInflater().inflate(R.layout.scheduledatetemplate, null);
date.setText(cancel.date);
TextView classname = (TextView) this.getLayoutInflater().inflate(R.layout.scheduleclasstemplate, null);
classname.setText(cancel.classname);
TextView lesson = (TextView) this.getLayoutInflater().inflate(R.layout.schedulelessontemplate, null);
lesson.setText(cancel.lesson);
Button details = (Button) this.getLayoutInflater().inflate(R.layout.detailsbuttontemplate, null);
details.setText(R.string.details);
details.setOnClickListener(this);
row.addView(date);
row.addView(classname);
row.addView(lesson);
row.addView(details);
table.addView(row);
}
}
And this is the TableLayout xml:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:scrollbars="vertical"
android:layout_height="fill_parent"
android:layout_width="fill_parent">
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/table"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical">
</TableLayout>
</ScrollView>
You need to declare android:layout_column and android:layout_span attributes to your TableRows
See http://developer.android.com/reference/android/widget/TableRow.LayoutParams.html
See an example here:
http://www.mkyong.com/android/android-tablelayout-example/
UPDATE:
Ok, you'll need to set the layout_span and layout_column in each of the rows you're creating, use this addView method:
http://developer.android.com/reference/android/widget/TableLayout.html#addView(android.view.View, int, android.view.ViewGroup.LayoutParams)
To supply the layout params with the appropriate column and span, to make your row span to the entire table, and have the row gravity=center to make their content in the center.
Also, the table attribute strechColumns
http://developer.android.com/reference/android/widget/TableLayout.html#attr_android:stretchColumns
Might help you, as in:
android:strechColumns="*"
or something like that.
I am using a custom Group indicator as shown in the code below. Now if I leave the default I can use setBounds perfectly, but when using my custom image which is the same dimensions and setup as the same .9 patch file it is always half off screen. No matter what values I use for setBounds()
Drawable plus = (Drawable) getResources().getDrawable(R.drawable.expander_group);
getExpandableListView().setGroupIndicator(plus);
Display newDisplay = getWindowManager().getDefaultDisplay();
int width = newDisplay.getWidth();
getExpandableListView().setIndicatorBounds(0,0);
XML expander_group
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_expanded="true"
android:drawable="#drawable/minus" />
<item
android:drawable="#drawable/plus" />
</selector>
EDIT:
Interestingly. I have copied the exact xml and image files from the standard Android files. And when I use the above method to define it the exact same thing happens! So it is not the xml or image files that are causing the issue I think.
How can I set the background color of an Activity to white programatically?
Add this single line in your activity, after setContentView() call
getWindow().getDecorView().setBackgroundColor(Color.WHITE);
Get a handle to the root layout used, then set the background color on that. The root layout is whatever you called setContentView with.
setContentView(R.layout.main);
// Now get a handle to any View contained
// within the main layout you are using
View someView = findViewById(R.id.randomViewInMainLayout);
// Find the root view
View root = someView.getRootView();
// Set the color
root.setBackgroundColor(getResources().getColor(android.R.color.red));
I prefer coloring by theme
<style name="CustomTheme" parent="android:Theme.Light">
<item name="android:windowBackground">#color/custom_theme_color</item>
<item name="android:colorBackground">#color/custom_theme_color</item>
</style>
?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FFFFFF"
android:id="#+id/myScreen"
</LinearLayout>
In other words, "android:background" is the tag in the XML you want to change.
If you need to dynamically update the background value, see the following:
Exercise: Change background color, by SeekBar
In your onCreate() method:
getWindow().getDecorView().setBackgroundColor(getResources().getColor(R.color.main_activity_background_color));
Also you need to add to values folder a new XML file called color.xml and Assign there a new color property:
color.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="main_activity_background_color">#000000</color>
</resources>
Note that you can name the color.xml any name you want but you refer to it by code as R.color.yourId.
EDIT
Because getResources().getColor() is deprecated, use getWindow().getDecorView().setBackgroundColor(ContextCompat.getColor(MainActivity.this, R.color.main_activity_background_color));
instead.
You can use this to call predefined android colours:
element.setBackgroundColor(android.R.color.red);
If you want to use one of your own custom colours, you can add your custom colour to strings.xml and then use the below to call it.
element.setBackgroundColor(R.color.mycolour);
However if you want to set the colour in your layout.xml you can modify and add the below to any element that accepts it.
android:background="#FFFFFF"
Button btn;
View root;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button)findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
root =findViewById(R.id.activity_main).getRootView();
root.setBackgroundColor(Color.parseColor("#FFFFFF"));
}
});
}
To get the root view defined in your xml file, without action bar, you can use this:
View root = ((ViewGroup) findViewById(android.R.id.content)).getChildAt(0);
So, to change color to white:
root.setBackgroundResource(Color.WHITE);
View randview = new View(getBaseContext());
randview = (View)findViewById(R.id.container);
randview.setBackgroundColor(Color.BLUE);
worked for me. thank you.
final View rootView = findViewById(android.R.id.content);
rootView.setBackgroundResource(...);
for activity
findViewById(android.R.id.content).setBackgroundColor(color)
The best method right now is of course
getWindow().getDecorView().setBackgroundColor(ContextCompat.getColor(MainActivity.this, R.color.main_activity_background_color));
Please be aware though, if you have anything set as the background color in Designer, it will overwrite anything you try to set in your code.