Load image into TextView's background - android

I have the following TextView layout:
<TextView
android:layout_width="10dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:drawableTop="#drawable/ic_launcher" >
I inflate this layout in code, and want to use Android-Universal-Image-Loader to load the image into drawableTop. But, as I understand, there's no way to get backgroundTop's ImageView from TextView, thus I can't use AUIL. Is there any way to get ImageView for background, and if not, how should I modify the layout so that it will have ImageView but will look the same as the original layout?

You can use listener (ImageLoadingListener) for that. Put following code in onLoadingComplete(...)
void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
Drawable topImage = new BitmapDrawable(loadedImage);
textView.setCompoundDrawablesWithIntrinsicBounds(null, topImage, null null);
}

Use a RelativeLayout with ImageView and TextView then manipulate ImageView
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_alignBottom="#+id/textView1"
android:layout_alignLeft="#+id/textView1"
android:layout_alignRight="#+id/textView1"
android:layout_alignTop="#+id/textView1"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</RelativeLayout>

TextView tv = (TextView) findViewById(R.id.TV);
Drawable top = getResources().getDrawable(R.drawable.icon) ;
tv.setCompoundDrawablesWithIntrinsicBounds(null, top, null, null) ;
// tv.setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom)

Related

Default Image in ImageView used in an Adapter

I just need a way to show default picture on all imageview ( see below ) used in a listview.
This layout is used by an adapter, so no setContentView function is called on this layout. I think this is causing the problem ( the default images doesn't appear ). How can I fix it ?
The image defaultpic.png is in the drawable folder and is 100x100px.
My code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="0dp"
android:paddingRight="0dp"
tools:context=".MainActivity"
android:background="#222222"
android:paddingTop="2dp"
android:paddingBottom="2dp">
<TextView
android:id="#+id/profile_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Title"
android:textColor="#fcdb8c"
android:background="#222222"
android:textStyle="normal"
android:textSize="15sp"
android:layout_alignParentTop="true"
android:lines="1"
android:scrollHorizontally="true"
android:ellipsize="end"
android:paddingRight="40dp"
android:paddingLeft="2dp" />
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:id="#+id/profile"
android:scaleType = "fitXY"
android:src="#drawable/defaultpic"
android:background="#151515"
android:padding="1dp" />
</RelativeLayout>
#Override
public View getView(View convertView, ViewGroup parent) {
RelativeLayout profileLay = (RelativeLayout)profileInf.inflate
(R.layout.profile_layout, parent, false);
TextView profileView = (TextView)profileLay.findViewById(R.id.profile_name);
ImageView coverView = (ImageView)profileLay.findViewById(R.id.profile);
profileView.setText(currProfile.getName());
Drawable img = Drawable.createFromPath(currProfile.getCover());
coverView.setImageDrawable(img);
return profileLay;
}
As k3b said:
your generated layout for the listviewitem has the image
therefore you do not see the default picture.
the way to correct this is to add an if statement.
ImageView coverView = (ImageView)profileLay.findViewById(R.id.profile);
if (Drawable.createFromPath(currProfile.getCover()) == null) {
Drawable img = Drawable.createFromPath(currProfile.getCover());
coverView.setImageDrawable(img);
}
This will cause it to only load the profile cover if it isn't null, but if it is then the default profile image will be used.
your generated layout for the listviewitem has the image
<RelativeLayout...>
<ImageView android:id="#+id/profile" android:src="#drawable/defaultpic" ... />
</RelativeLayout>
and when the listviewitem is created you immediately overwrite the picture in the imageview
#Override
public View getView(View convertView, ViewGroup parent) {
...
ImageView coverView = (ImageView)profileLay.findViewById(R.id.profile);
Drawable img = Drawable.createFromPath(currProfile.getCover());
coverView.setImageDrawable(img);
...
therefor you do not see the default picture

Android capture layout in app

I'm trying to capture my app screen, not all of it only the linear layout.
atm I'm using this which I think should work, but IDK y it's not. It captures all the screen of the phone not only the linearlayout which I wants it to
final LinearLayout ll = (LinearLayout) findViewById(R.id.Linear);
View v1 = ll.getRootView();
v1.setDrawingCacheEnabled(true);
Bitmap bm = v1.getDrawingCache();
part of my xml:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="#+id/Linear" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent" >
<ImageView
android:layout_width="60dp"
android:layout_height="60dp" />
</RelativeLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="10dp" />
<ImageView
android:layout_width="15dp"
android:layout_height="18dp"
android:layout_marginRight="10dp"
android:src="#drawable/ll" />
<ImageView
android:layout_width="15dp"
android:layout_height="20dp"
android:src="#drawable/lle" />
</LinearLayout>
atm it should capture the linearlayout which contains only 3imageviews and 2 textviews, but it captures all the xml or the screen.
Your problem is that you are asking for the root view, which is "all the xml". Instead, you should be just using your LinearLayout:
final LinearLayout ll = (LinearLayout) findViewById(R.id.Linear);
ll.setDrawingCacheEnabled(true);
Bitmap bm = ll.getDrawingCache();
by using this we can capture layout and save in to sd card.
ok.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
l1.setDrawingCacheEnabled(true);
img_bitmap = Bitmap.createBitmap(l1.getDrawingCache());
l1.setDrawingCacheEnabled(false);
}
});
}

ImageView doesn't fill the height of its layout

I wish to add an ImageView inside a ListView. I would like the image to fill the layout without distorsion (basically, fill the height and adapt its width).
This is what I get now:
I have put a grey background to the ImageView to make it easier to see. In red, it's the size I wish to get.
Here is my code:
Project_form.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/name_project"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:padding="3dp"
android:layout_alignParentLeft="true"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="25dp" >
</TextView>
<Button
android:id="#+id/button_project"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/btn_custom"
android:layout_centerVertical="true"
android:focusable="false"
android:focusableInTouchMode="false"
android:layout_alignParentRight="true"
android:padding="3dp"
android:text=" details "
android:textSize="20dp"
android:visibility="invisible" />
<ImageView
android:id="#+id/imagesstep"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:background="#color/grey"
android:adjustViewBounds="false"
android:layout_centerVertical="true"
android:padding="3dp"
android:layout_alignParentRight="true"
android:visibility="invisible" />
</RelativeLayout>
method getView() of my Adapter :
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row==null) {
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.project_form, parent, false);
}
TextView text = (TextView) row.findViewById(R.id.name_project);
text.setText(this.objects[position].getName());
int IDImage=this.objects[position].getIDImage();
int IDPlay = this.objects[position].getIDPlay();
text.setCompoundDrawablesWithIntrinsicBounds(IDImage, 0, 0, 0);
text.setCompoundDrawablePadding(7);
ImageView image = (ImageView)
row.findViewById(R.id.imagesstep);
image.setVisibility(View.VISIBLE);
image.setImageResource(IDPlay);
if (position == selectedPosition) {
row.setBackgroundColor(Color.parseColor("#8000ff00"));
}
else {
row.setBackgroundColor(Color.TRANSPARENT);
}
return row;
}
I tried to play with different parameters such as ScaleType, android:adjustViewBounds and layout_width but the height of my image never changed. I also tried to do it programatically (something like image.setMinHeight(parent.getHeight()) but it failed too.
Could anyone point me out what is going wrong?
Many thanks
Try changing the RelativeLayout of the layout_height to fill_parent
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="fill_parent">
<TextView ... />
<Button .. />
<ImageView ... />
</RelativeLayout>
Alternatively you could set the minHeight attribute of the ImageView to ?android:attr/listPreferredItemHeight
<ImageView
...
android:minHeight="?android:attr/listPreferredItemHeight" />
Remove the padding from your imageview

Android: Last line of textview cut off

I have a horizontal LinearLayout containing a TextView followed by a Spinner next to it. This LinearLayout is dynamically inflated multiple times in a fixed vertical LinearLayout contained within a RelativeLayout.
The problem is that since I switched from Theme.light to Theme.holo.light, the last line of the TextView gets cut in half. This happens when the dynamic text is long and spans more than one row.
I have been able to fix this by adding bottom padding to the horizontal LinearLayout containing the TextView and Spinner.
This does not feel like a fix, but more of a hack. Can someone please give me some advice on how to properly fix this?
I have also read some other questions, but none seem to help.
Horizontal Linear layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/textView1"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:text="TextView"/>
<Spinner
android:id="#+id/spinner1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Relative layout where above layout is dynamically inflated at Linear Layout with id ll2_7:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ScrollView
android:id="#+id/scrollView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/relLayoutButtonNext"
android:layout_below="#id/textView1" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="20dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp" >
<TextView
android:id="#+id/textView10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="30dp"
android:text="2.7" />
<TextView
android:id="#+id/textView11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_toRightOf="#id/textView10"
android:text="#string/question2_7" />
<LinearLayout
android:id="#+id/ll2_7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView11"
android:layout_below="#+id/textView11"
android:orientation="vertical" android:layout_marginBottom="20dp">
</LinearLayout>
</RelativeLayout>
</ScrollView>
</RelativeLayout>
EDIT:
Here is the complete layout xml for above:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/textView1"
style="#style/question_section_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="#string/question2_header" />
<RelativeLayout
android:id="#+id/relLayoutButtonNext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#color/bottomBar"
android:paddingBottom="3dp"
android:paddingLeft="50dp"
android:paddingRight="50dp"
android:paddingTop="3dp" >
<Button
android:id="#+id/buttonNext"
android:layout_width="180dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:onClick="nextStep"
android:text="Next Section"
android:textSize="20sp" />
<Button
android:id="#+id/buttonPrevious"
android:layout_width="180dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:onClick="previousStep"
android:text="Previous Section"
android:textSize="20sp" />
</RelativeLayout>
<ScrollView
android:id="#+id/scrollView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/relLayoutButtonNext"
android:layout_below="#id/textView1" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="20dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp" >
<TextView
android:id="#+id/textView10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="30dp"
android:text="2.7" />
<TextView
android:id="#+id/textView11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_toRightOf="#id/textView10"
android:text="#string/question2_7" />
<LinearLayout
android:id="#+id/ll2_7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView11"
android:layout_below="#+id/textView11"
android:orientation="vertical" android:layout_marginBottom="20dp">
</LinearLayout>
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView10"
android:layout_below="#+id/ll2_7"
android:text="2.8" />
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/ll2_7"
android:layout_toRightOf="#+id/textView10"
android:text="#string/question2_8" android:layout_marginBottom="10dp"/>
<LinearLayout
android:id="#+id/ll2_8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView3"
android:layout_below="#+id/textView3"
android:layout_marginBottom="20dp"
android:orientation="vertical" >
</LinearLayout>
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView2"
android:layout_below="#+id/ll2_8"
android:text="2.9" />
<TextView
android:id="#+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/ll2_8"
android:layout_toRightOf="#+id/textView10"
android:text="#string/question2_9" android:layout_marginBottom="10dp"/>
<LinearLayout
android:id="#+id/ll2_9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView5"
android:layout_toRightOf="#+id/textView10"
android:orientation="vertical" android:layout_marginBottom="20dp">
</LinearLayout>
<TextView
android:id="#+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView4"
android:layout_below="#+id/ll2_9"
android:text="2.10" />
<TextView
android:id="#+id/textView7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/ll2_9"
android:layout_toRightOf="#+id/textView10"
android:text="#string/question2_10" android:layout_marginBottom="10dp"/>
<LinearLayout
android:id="#+id/ll2_10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView7"
android:layout_marginBottom="20dp"
android:layout_toRightOf="#+id/textView10"
android:orientation="vertical" >
</LinearLayout>
<TextView
android:id="#+id/textView8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView6"
android:layout_below="#+id/ll2_10"
android:text="2.11" />
<TextView
android:id="#+id/textView9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/ll2_10"
android:layout_toRightOf="#+id/textView10"
android:text="#string/quesiton2_11" android:layout_marginBottom="10dp"/>
<LinearLayout
android:id="#+id/ll2_11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView9"
android:layout_below="#+id/textView9"
android:orientation="vertical" android:layout_marginBottom="20dp">
</LinearLayout>
<TextView
android:id="#+id/textView12"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView8"
android:layout_below="#+id/ll2_11"
android:text="2.11.1" />
<TextView
android:id="#+id/textView13"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/ll2_11"
android:layout_toRightOf="#+id/textView10"
android:text="#string/question2_11_1" android:layout_marginBottom="10dp"/>
<LinearLayout
android:id="#+id/ll2_11_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView13"
android:layout_toRightOf="#+id/textView10"
android:orientation="vertical" android:layout_marginBottom="20dp">
</LinearLayout>
</RelativeLayout>
</ScrollView>
</RelativeLayout>
I applied a LayoutGravity to the TextView item:
android:layout_gravity="fill"
I've encountered the same cut-off issue as shown at the screenshot. It is caused by the baseline alignment in the horizontal LinearLayout. TextView and Spinner have different baselines due to font size difference. To fix the issue it is needed to disable baseline alignment for the layout by setting:
android:baselineAligned="false"
or in the code:
layout.setBaselineAligned(false);
I had the same problem, and found that simply adding
android:includeFontPadding="false"
the final line of text no longer had its descenders clipped.
I added some dummy space after text by adding
textView.setText(firstString+"\n");
I tried all other solution.But this was the only solution worked for me
I found a different solution by extending TextView and adding a custom Class like this:
public class AdaptingTextView extends TextView {
public AdaptingTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public AdaptingTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AdaptingTextView(Context context) {
super(context);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// set fitting lines to prevent cut text
int fittingLines = h / this.getLineHeight();
if (fittingLines > 0) {
this.setLines(fittingLines);
}
}
}
Put the problematic textview inside a framelayout. I think the text view is not calculated correctly because of the sibling view, Spinner.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<FrameLayout
android:layout_width="150dp"
android:layout_height="wrap_content">
<TextView
android:id="#+id/textView1"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:text="TextView"/>
</FrameLayout>
<Spinner
android:id="#+id/spinner1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
When this occurs, you should ensure that the TextView is not growing larger than it's container -
If a TextView is set to wrap_content and it's container (or an ancestor container) doesn't leave room for the TextView to grow into it can be occluded.
If that's not the case, it's also possible the onMeasure() of the TextView sometimes doesn't correctly measure the tails of letters, non-latin characters or the effects from text being italic. You can correct for this by setting a global style for your TextView so it will be picked up without needed to change your entire code base:
Ensure that you're application/activities use a custom theme like so:
<style name="Custom" parent="#android:style/Theme.Light">
<item name="android:textViewStyle">#style/Custom.Widget.TextView</item>
</style>
<style name="Custom.Widget.TextView" parent="#android:style/Widget.TextView">
<item name="android:gravity">fill</item>
<item name="android:padding">1sp</item>
</style>
The answer by #Rynadt was really helpful in getting to the above stage. Setting the gravity of the Text inside the View ensures on some devices that occlusion never takes place (The text is correctly fitted inside the view), on others a helping hand with padding of an sp value, ensures that the tails et al are accounted for with a TextSize specific value.
My solution was close to the accepted one, but I had to change it to
android:layout_gravity="fill_vertical"
instead. Otherwise the other rows would have been stretch as well with added line breaks at random places. For example, the biggest row had 4 lines, so another row was changed from
this is a testphrase
to
thi
s is
a testph
rase
try with removing android:paddingBottom="20dp"
from
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="20dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp" >
getViewTreeObserver().addOnGlobalLayoutListener does not work in a recycler view. If you're using a recycler, use View.addOnLayoutChangeListener:
I found that the ellipsizing I defined for textView in xml was not always reflected so I programmatically set it before reassigning the text property. This worked for me.
textView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
#Override
public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
textView.removeOnLayoutChangeListener(this);
float lineHeight = textView.getLineHeight();
int maxLines = (int) (textView.getHeight() / lineHeight);
if (textView.getLineCount() != maxLines) {
textView.setLines(maxLines);
textView.setEllipsize(TextUtils.TruncateAt.END);
// Re-assign text to ensure ellipsize is performed correctly.
textView.setText(model.getText());
}
}
});
If you have this problem and your TextView is inside a RelativeLayout, try switching the RelativeLayout for a LinearLayout.
That fixed the problem for me
You can use a global layout listener for a TextView in any type of ViewGroup.
final TextView dSTextView = (TextView)findViewById(R.id.annoyingTextView);
dSTextView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
dSTextView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
float lineHeight = dSTextView.getLineHeight();
int maxLines = (int) (dSTextView.getHeight() / lineHeight);
if (dSTextView.getLineCount() != maxLines) {
dSTextView.setLines(maxLines);
}
}
});
You can read more about it here
I know it's so late, but this is work like charm for me.
add this code to your textview
android:ellipsize="marquee"
android:layout_weight="1"
I think there is very little you can do to get this working by altering the layouts. As I have found that some methods work only in some cases. I think it depends on the entire layout hierarchy and is not a one-size-fits-all solution. I have also noticed that it happens especially when you have a different font that you want to set to the TextView.
A sure shot method that I have experimented and tested is that you can set the font attributes in code after the view is inflated. I am assuming that you have a font in the assets/fonts folder that you want to you.
For eg in a Fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_view, container, false);
TextView tv = (TextView)view.findViewById(R.id.text_view);
tv.setText("Insert text that needs to be displayed");
AssetManager assetManager = getContext().getAssets();
Typeface typeFace = Typeface.createFromAsset(assetManager, "Fonts/OpenSans-Light.ttf");
tv.setTypeface(typeFace , 0); // 0 is normal font
tv.setPadding(10, 0, 10, 0); // This is not mandatory
}
And in an Activity:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(Resource.Layout.main_activity);
TextView tv = (TextView)this.findViewById(R.id.text_view);
tv.setText("Insert text that needs to be displayed");
AssetManager assetManager = getContext().getAssets();
Typeface typeFace = Typeface.createFromAsset(assetManager, "Fonts/OpenSans-Light.ttf");
tv.setTypeface(typeFace , 0); // 0 is normal font
tv.setPadding(10, 0, 10, 0); // This is not mandatory
}
I have this same problem, and its very annoying.
It only happens with Arabic text.
If you make the label multi-line and adding a \n at the end of your string, it would fix it, but the problem is that there would be a big gap between this label and the object below it, due to the fact that this field now has a new empty line below it.
A custom control can be done to get around that. But overall, this is an annoying bug.
Best workaround for this is to add a dummy View of desired height (i.e. this will add padding itself) at the bottom of your view.
<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp" >
<View
android:layout_width="match_parent"
android:layout_height="30dp"/>
</TableRow>
Like in my case I added one more table row at the bottom of the view. Hope this could help someone.
Add padding to the bottom of the text view:
android:paddingBottom="24dp"
I had the same problem and found a handy solution. I get the number of lines of the TextView after rendering and set the height according to the number of lines. Here is the code.
TextView textView = (TextView) layout.findViewById(R.id.textView);
textView.setText(this.text);
textView.post(new Runnable() {
#Override
public void run() {
int linesCount = textView.getLineCount();
textView.setLines(linesCount);
}
});
For me, this solution worked like a charm.
The height and width of my outermost layout was set dynamically, so the TextView contained within got it's text cut even if I set android:maxLines in my xml (for different devices it was behaving differently).
After trying out different methods, finally I got a solution that fixed my issue.
Textview:
public class CustomTextView extends androidx.appcompat.widget.AppCompatTextView {
public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomTextView(Context context) {
super(context);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// set fitting lines to prevent cut text
int fittingLines = h / this.getLineHeight();
if (fittingLines > 0) {
this.setLines(fittingLines);
this.setEllipsize(TextUtils.TruncateAt.END);
}
}
}
xml:
<com.myproject.android.customviews.CustomTextView
android:id="#+id/tv_partner_description"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="top"
android:textColor="#color/white"
android:textSize="#dimen/text_small_medium" />
create theme as for particular language like style-ar which cut-off textview:
<style name="EnnodaCustomTextView" parent="Widget.AppCompat.TextView">
<item name="android:paddingTop">1dp</item>
<item name="android:paddingBottom">1dp</item>
</style>
Apply it in you AppTheme to reflect in overall app for padding bottom, as :
<item name="android:textViewStyle">#style/EnnodaCustomTextView</item>
Note : create same style name in default styles.xml with no item tags for padding..(where no need of extra padding )
I finally fixed it!
I try to add String to the TextView in Service and then call scrollTo(), the last line be cut off!
The scrollTo() should be call in "Runnable", like:
private ScrollView mScrollView;
public void scrollToBottom()
{
mScrollView = (ScrollView) findViewById(R.id.debug_textview_scrollview);
mScrollView.post(new Runnable()
{
public void run()
{
mScrollView.fullScroll(View.FOCUS_DOWN);
}
});
}
I think it because in the monent of call scrollTo() in service, the update of TextView is not ready.

Taking a "screenshot" of a specific layout in Android

I have two main issues which are closely linked. I am looking at these problems from a programmatic point of view.
(1) - I wish to take a screenshot of the contents of a SPECIFIC layout, i.e. a ScrollView nested in a LinearLayout.
(2) - As the ScrollView has content that spills out of the screen (hence scrolling made possible), how can I ensure that the screenshot includes the elements that are not visible on the screen?
This is the current block of code I use. It does the job of taking a screenshot but only for the entire screen. This is even though R.id.boss is the ID of the ScrollView and not the main LinearLayout.
View view = findViewById(R.id.boss);
View v = view.getRootView();// this does not seem to make a difference
v.setDrawingCacheEnabled(true);
v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
v.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(u.getDrawingCache());
v.setDrawingCacheEnabled(false);
Thanks in advance.
EDIT:
I've made a few mistakes. I used R.id.boss which is the wrong resource. I am now able to take a screenshot of the scrollview alone, less the out-of-screen parts.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/boss"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="top"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="F"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Analyze via image URL"
android:textAppearance="?android:attr/textAppearanceSmall" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<EditText
android:id="#+id/mUrl"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.7"
android:text="http://" >
<requestFocus />
</EditText>
<ImageView
android:id="#+id/call"
android:layout_width="75dp"
android:layout_height="50dp"
android:layout_weight="0.3"
android:text="ABC"
android:src="#drawable/run" />
</LinearLayout>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="ABC"
android:textAppearance="?android:attr/textAppearanceSmall" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<EditText
android:id="#+id/filepath"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.55" />
<ImageView
android:id="#+id/cam"
android:layout_width="75dp"
android:layout_height="50dp"
android:layout_weight="0.15"
android:src="#drawable/cam" />
<ImageView
android:id="#+id/browse"
android:layout_width="75dp"
android:layout_height="50dp"
android:layout_weight="0.15"
android:src="#drawable/folder"
android:text="B" />
<ImageView
android:id="#+id/upload"
android:layout_width="75dp"
android:layout_height="50dp"
android:layout_weight="0.15"
android:src="#drawable/run"
android:text="A" />
</LinearLayout>
<LinearLayout
android:id="#+id/baba"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ScrollView
android:id="#+id/scroll"
android:layout_width="fill_parent"
android:layout_height="150dp"
android:layout_weight="0.7" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="186dp"
android:orientation="vertical" >
<ImageView
android:id="#+id/pic"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Facial recognition"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/text3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="#+id/avmarwe"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Gender and age"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="#+id/skahasd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Expression and mood"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="#+id/dsfsfs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Celebrity Facial Match"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/text4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</ScrollView>
</LinearLayout>
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom" >
<Button
android:id="#+id/c"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_weight="0.7"
android:text="" />
<Button
android:id="#+id/share"
android:layout_width="70dp"
android:layout_height="50dp"
android:layout_weight="0.3"
android:text="" />
</LinearLayout>
</LinearLayout>
Thanks to you guys, I've finally found out what was wrong.
View v = view.getRootView(); should not be used because it will call the root view which I do not want. I mistakenly thought this did not make a difference because I had entered the wrong resource ID.
MeasureSpec somehow did not give a good account of the width and height. So I ended up using another method:
...
ScrollView z = (ScrollView) findViewById(R.id.scroll);
int totalHeight = z.getChildAt(0).getHeight();
int totalWidth = z.getChildAt(0).getWidth();
u.layout(0, 0, totalWidth, totalHeight);
...
As ScrollView's total height can be determined by the single child element that it has.
After making these changes, I am now able to take a screenshot of a nested ScrollView and all its contents, visible or not. For anyone interested, here is the block of code including the saving of the bitmap:
View u = findViewById(R.id.scroll);
u.setDrawingCacheEnabled(true);
ScrollView z = (ScrollView) findViewById(R.id.scroll);
int totalHeight = z.getChildAt(0).getHeight();
int totalWidth = z.getChildAt(0).getWidth();
u.layout(0, 0, totalWidth, totalHeight);
u.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(u.getDrawingCache());
u.setDrawingCacheEnabled(false);
//Save bitmap
String extr = Environment.getExternalStorageDirectory().toString() + File.separator + "Folder";
String fileName = new SimpleDateFormat("yyyyMMddhhmm'_report.jpg'").format(new Date());
File myPath = new File(extr, fileName);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(myPath);
b.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
MediaStore.Images.Media.insertImage(getContentResolver(), b, "Screen", "screen");
}catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try this it works fine for me
TableLayout tabLayout = (TableLayout) findViewById(R.id.allview);
if (tabLayout != null) {
Bitmap image = Bitmap.createBitmap(tabLayout.getWidth(),
tabLayout.getHeight(), Config.ARGB_8888);
Canvas b = new Canvas(image);
tabLayout.draw(b);
}
EDIT : after seeing OP's comment
You dont need to think about new activities at all.. Say you are in Activity right now.. Layout A is the main layout for the activity, Layout B and C are two child layouts inside Layout A. Like this,
Layout A -> Parent
|
-------Layout B
|
-------Layout C
Now if you want to take screenshot of C only
1) in onCreate() of activity
LinearLayout myCLayout = (LinearLayout)this.findViewbyId(R.id.my_c_layout);
ViewTreeObserver vto = myCLayout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
//fully drawn, no need of listener anymore
myCLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
getDrawingBitmap();
}
});
where getDrawingBitmap() is a function..to take your screenshot..
public void getDrawingBitmap(){
LinearLayout myCLayout = (LinearLayout)this.findViewbyId(R.id.my_c_layout);
Bitmap b = myCLayout.getDrawingCache();
File file = saveBitmapAsFile(b);
}
EDIT: For ScrollView
I never tried it.. But I think you can do this..
1) first override scrollView, and override onMeasure function..
public class MyScrollView extends ScrollView{
public MyScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(widthMeasureSpec, yourFullScrollViewHeight));
}
}
and use MyScrollView in your layout.. here yourFullScrollViewHeight is the height of all scrollView content you need to take screenshot of.. I never tried this.. But it might work..
Here is the exact solution you want, It will display entire screen including content hidden in your ScrollView
LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
FrameLayout root = (FrameLayout) inflater.inflate(R.layout.activity_main, null); // activity_main is UI(xml) file we used in our Activity class. FrameLayout is root view of my UI(xml) file.
root.setDrawingCacheEnabled(true);
Bitmap bitmap = getBitmapFromView(this.getWindow().findViewById(R.id.frameLayout)); // here give id of our root layout (here its my FrameLayout's id)
Display bitmap in your ImageView or use it as you want. Enjoy..
I also had this problem and coded it myself.
I used this code to take screenshot of whole layout.
I did modified the list size and some mathematical items.
See the following website,
Try this code
public Bitmap screenShot(View view)
{
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),
view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}

Categories

Resources