I am trying to create a custom preference used in a fragment. That preference will have an icon, a long text and a hyperlink to link somewhere.
For that I create a class that extends androidx.preference.Preference
The constructor is this:
public MyCustomPreference(Context context, AttributeSet attrs) {
super(context, attrs);
this.setWidgetLayoutResource(R.layout.my_custom_preference_layout);
}
I get it to work correctly and all that, but the problem is that its height is way too short. The preference size doesn't fit its content. It seems like it is always the same size. About two lines of text only.
I have tried with
android:singleLine="false"
android:minLines="50"
but nothing. The preference is displayed way too short.
Is there any limitation in the height of custom preferences?
I use a RelativeLayout for the layout and add the controls I need to it.
that Relative Layout have these values:
android:layout_width="match_parent"
android:layout_height="wrap_content"
I have tried setting match_parent to both, even setting a fixed value, for example 500dp, but it is always displayed in small height.
Related
Can anyone explain to me why this is happening?
I have a fairly simple class extending TextView. When I set the background colour to Color.BLUE, padding works fine. When I change the background resource to android.R.drawable.list_selector_background, my padding is no longer applied. What the F?
Here is my UI class:
public class GhostDropDownOption extends TextView {
TextView text_view;
public GhostDropDownOption(Context context, AttributeSet attrs) {
super(context, attrs);
setup(context);
}
public GhostDropDownOption(Context context) {
super(context);
setup(context);
}
private void setup(Context context) {
this.setClickable(false);
// THE 2 LINES BELOW ARE THE ONLY THING I'M CHANGING
//this.setBackgroundResource(android.R.drawable.list_selector_background);
this.setBackgroundColor(Color.BLUE);
}
}
And I'm using it in the layout like this:
<trioro.voyeur.ui.GhostDropDownOption
android:id="#+id/tv_dropdown_option_1"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:gravity="center_vertical"
android:text="#string/request_control_dropdown_option_1"
android:textColor="#000000"
android:padding="10dip"/>
And this is the result of changing the background:
The call to:
this.setBackgroundResource(android.R.drawable.list_selector_background);
will remove any previosly set padding (this is to make it work properly with 9-patch assets).
Try to set the padding in code after the line above, like this:
this.setPadding(PADDING_CONSTANT, PADDING_CONSTANT, PADDING_CONSTANT, PADDING_CONSTANT);
Just remember that the values sent to setPadding is in pixels NOT dip!
You should set your background drawable in XML if at all possible. If you set it in code, it will use the padding from your drawable resources rather than what you set in XML, so if it's necessary to do it programmatically, you'll want to retrieve the current padding, store it temporarily, set the background, and then set the padding back as #TofferJ suggests.
The reason for this is that the drawables themselves can have padding, in the case of 9-patch images (where the bottom and right pixel borders define the amount of padding).
Your solution should be to just set your background resource in XML:
android:background="#android:drawable/list_selector_background"
although I believe that may be a private drawable resource that you'll have to copy into your project first.
I created a background image bitmap for a view and now the view is being stretched to the size of the background image....
is this normal?
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/green"
android:tileMode="repeat"/>
here's how I apply it to my view
v.setBackgroundResource(R.drawable.backgroundgreen);
for instance...
if the image is 500px in height
and the view is 200px in height(being set wrap_content as height)
after setting the image as background my view becomes 500px in height...
I have faced this same problem.
If the background image has a size that is bigger than the view's size, the view's size will change to match the image's size.
Solution
Put the view inside a Relative Layout.
Remove the background image.
Add an ImageView before the View inside the Relative Layout
Set the src of the ImageView to your background image
<RelativeLayout
.
.
. >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/yourViewId"
android:layout_alignRight="#+id/yourViewId"
android:layout_alignTop="#+id/yourViewId"
android:layout_alignBottom="#+id/yourViewId"
android:adjustViewBounds="true"
//this will allow the image to resize with same proportions
android:src="#drawable/yourDrawable" />
<YourView
android:id="#+id/yourViewId"
.
..
... />
</RelativeLayout>
This all can be done in code of course.
According to me, the problem you are facing is not a problem, it is the way how Android is used to design the layouts.
This means that you can set the height and width with 3 default constant values:
FILL_PARENT
Special value for the height or width requested by a View. FILL_PARENT means that the View wants to be as big as its parent, minus the parent's padding if any. This value is deprecated starting in API Level 8 and replaced by MATCH_PARENT.
MATCH_PARENT
Special value for the height or width requested by a View. MATCH_PARENT means that the view wants to be as big as its parent, minus the parent's padding if any. Introduced in API Level 8.
WRAP_CONTENT
Special value for the height or width requested by a View. WRAP_CONTENT means that the View wants to be just large enough to fit its own internal content, taking its own padding into account.
Now, when you are setting the View's height/width to WRAP_CONTENT, you are allowing the view to take that much size that is sufficient to show to view's content. The background image is also the View's content, hence you view will be shown of as much size as the image. That's not a problem, that's how it's shown.
Okay, but in your situation that's an issue for you because you have a background to show and view should not be stretched for that. I can suggest few ways:
First and very obvious: make correctly sized images and keep them in different drawable folders.
Specify the size of view not using constants, but in DP. If it becomes necessary, make different layout XML files for different sizes and keep them in layout folders.
You can use a very useful thing for design layout is layout weight.
I suggest to create a wrapper layout and put the background image in there. i'm using it that way and fits very nicely.
see example below
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/settingstab_scroll"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars="vertical"
android:background="#drawable/wareninja_wallpaper_img"
>
<!-- your layouts and components goes here -->
</ScrollView>
...
Social Coding # AspiroTV
The reason is quite simple. You gotta see the View::getSuggestedMinimumWidth/Height method.
protected int getSuggestedMinimumWidth() {
return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());
}
protected int getSuggestedMinimumHeight() {
return (mBackground == null) ? mMinHeight : max(mMinHeight, mBackground.getMinimumHeight());
}
Seeing that, you may know why the background makes a view bigger, especially why assign a BitmapDrawable to it.
and the simple solution is to wrap that Drawable (eg. BitmapDrawable), then returns 0 for getMinimumHeight() and getMinimumWidth(), and better to override getIntrinsicHeight() and getIntrinsicWidth() to returns -1.
support-v7 has a DrawableWrapper which delegates calls to another drawable when necessary. you can extends that one and override methods talked above.
and if you don't use support-v7 (WoW! you are awesome), copy that class to your project is also fine.
https://android.googlesource.com/platform/frameworks/support/+/1949ae9aeaadf52ad7bd7bb74ca5419c67ea7f65/v7/appcompat/src/android/support/v7/internal/widget/DrawableWrapper.java
It's working for me.
< ?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:id="#+id/LinearLayoutTest">
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.prueba);
((LinearLayout)findViewById(R.id.LinearLayoutTest)).setBackgroundResource(R.drawable.greenrepeat);
}
in your code, what is v? It has params to fill_parent?
Don't use android:tileMode="repeat". Is your green drawable bigger or smaller than your view? Could add more details?
One good solution that is working perfectly in my case is extending the View and overriding onMeasure().
Here is the steps to do:
Create an own class and extend the View you want to use, here for
example I will use Button.
Override the method onMeasure() and insert the code at the bottom. This will set the background resource after the first measure has been done. For the second measure event, it will use the already measured paramters.
Example code for a custom view which extends Button (change Button to the View you would like to extend)
public class MyButton extends Button {
boolean backGroundSet = false;
public MyButton(Context context) {
super(context);
}
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if(backGroundSet) {
setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight());
return;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
backGroundSet = true;
setBackgroundResource(R.drawable.button_back_selector);
}
}
The only thing to change here is the type of view you want to extend and in the onMeasure() method the background resource you want to use for the view.
After that, just use this view in your layout xml or add it programatically.
I modify Sherif elKhatib's code, now this works for me:
if we want background picture be stretched as view picture:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignStart="#+id/yourViewId"
android:layout_alignTop="#+id/yourViewId"
android:layout_alignEnd="#+id/yourViewId"
android:layout_alignBottom="#+id/yourViewId"
android:scaleType="fitXY"
android:src="#drawable/bg_very_big_picture" />
<LinearLayout
android:id="#+id/yourViewId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
if we want background picture not to be stretched, but to be cutted to fit view picture:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignStart="#+id/yourViewId"
android:layout_alignTop="#+id/yourViewId"
android:layout_alignEnd="#+id/yourViewId"
android:layout_alignBottom="#+id/yourViewId"
android:scaleType="centerCrop"
android:src="#drawable/bg_very_big_picture" />
<LinearLayout
android:id="#+id/yourViewId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
I have a list, each row in the list has text. Some of the text extends beyond the edge of the screen. I have no problem making it truncate the text and show ellipses. I have no problem to 'fade the edge of the text' however, the fade occurs at the edge of every text, not just the ones the are too large for the textview.
I have searched and searched and can't find a way to, essentially, do exactly what the ellipses do, but, instead of ellipses, fade the edge of the text only if it is going off the edge of the screen. Can anyone please help? Right now, my text view contains:
android:fadingEdge="horizontal"
android:inputType="text"
android:maxLines="1"
I have tried many other things to no avail.
To enable marquee and simulateouly not affecting the list Selections Just use following:
In the code just use two methods on that text View.
textViewObj.setSelected(true);
textViewObj.setEllipsize(TextUtils.TruncateAt.MARQUEE);
The specific method call to enable the horizontal edge fade (on the right-hand side) is
setHorizontalFadingEdgeEnabled(true)
Here is an example from the constructor in my class ScrollTextView, which extends TextView:
public ScrollTextView(Context context, AttributeSet attrs) {
this(context, attrs, android.R.attr.textViewStyle);
setHorizontalFadingEdgeEnabled(true);
}
Im kind of new to Android.
I am playing around with the Android FingerPaint API Sample. I have figured out how to add buttons and functions to the Menu, but how do I get buttons on the actual screen?
Is it possible to place buttons over the drawing surface? Or would I need a linear (Vertical) layout on the left, and place buttons in there. Either would be fine.
Help? Thanks.
The Android FingerPaint sample code does not use a layout; it instead just has a subclass of View called MyView, and then the Activity sets its content view to be an instance of MyView.
If you want to have more than one View on the screen, you'll need to use some sort of layout. You could use a LinearLayout if you want the MyView for painting to be above, below, or to the side of the buttons; if you want the buttons to be on top of the MyView, take a look at using a FrameLayout or RelativeLayout.
You can either then define the layout in XML or create it manually in code. The former is more flexible and maintainable, but there will be a few hiccups.
First, create a layout XML showing how you want your components to be laid out. For this example, we'll call it finger_paint.xml. Make sure you have a MyView in there somewhere, something like:
<view class="com.example.android.apis.graphics.FingerPaint$MyView"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
Then, replace the line that looks like
setContentView(new MyView(this));
with
setContentView(R.layout.finger_paint);
Note that because MyView does not (yet) have the proper constructor for being instantiated by the LayoutInflater, this will not work yet, so let's fix that. Add an additional import near the top of the file:
import android.util.AttributeSet;
and then add an AttributeSet parameter to the constructor of MyView:
public MyView(Context c, AttributeSet as) {
super(c, as);
// rest of constructor is same as in the sample
}
You will also have to change MyView to be a static inner class of FingerPaint.
You may find the Building Custom Components document and the NotePad sample useful as you figure this out.
Good luck!
Are you trying to dynamically position your buttons?
If so, you can use setLayoutParams to set the layout properties of the button.
I want to add a new view to my scene that will contain content that will change programatically throughout the course of my application. When it does change, it needs to pop up on the screen for 3 seconds (or a click) then disappear.
This view will change in size according to its content WRAP_CONTENT, but ideally I'd like it centered horizontally and vertically on the screen.
I'm stuck on three parts:
1) what type of view should I use for this...I was thinking Relative, but all of my playing with it has yielded no good results for what I'm trying to do
2) with respect to #1 (trying relative view), I could not get it centered properly (tried using param.leftMargin and param.topMargin with varying values but could not get it to work on different devices with different resolutions
3) also with respect to #1, I couldn't make this float over everything else on my screen (need something like a z-index or the like).
any ideas, code examples would be wonderful.
TIA
Use a custom dialog, i.e. a LinearLayout with android:theme="#android:style/Theme.Dialog" and for the class, it would be something like
public class YourCustomDialog extends Dialog implements DialogInterface
where you can implement you custom logic of what to display. Such dialog is floating and modal on top of all other views then and you can also optionally set the background to blurry, etc.
This is a typical constructor of my custom dialog - the layout would be defined in an xml layout file, which in my case is my_custom_dialog.xml:
public MyCustomDialog(Context context) {
super(context, android.R.style.Theme);
Window window = getWindow();
window.requestFeature(Window.FEATURE_NO_TITLE);
window.setGravity(Gravity.BOTTOM);
window.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.empty));
setContentView(R.layout.my_custom_dialog);
// actually not necessary as it's already the default value:
window.setLayout(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
...
}