I am using Kotlin in AS and am relatively new to it so I will try to explain as best I can. I am also using a database that stores food products and their images.
I am converting a varbinary to a bitmap and setting the bitmap in a viewHolder that is a place holder for my images. When running my app, the image is
cutoff as shown
and I'm unsure why it is being cut off as such.
For now, I am hardcoding in one of the records from my image column
val imageText = "89504E47..."
and setting the image bitmap by running the string into a function that gets the bitmap and sets it to my viewHolder
viewHolder.productImg.setImageBitmap(getBitmap(imageText))
/**
* Converts a hex string to Bitmap
*
* #param image hex string e.g. "FFD8FFE0..."
* #return Bitmap
*/
private fun getBitmap(image: String): Bitmap {
// Convert String to ByteArray
val byteArray = Hex.stringToBytes(image)
// Convert ByteArray Bitmap
return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size)
}
I tried playing with the XML that contains the ImageView but that does nothing
<ImageView
android:id="#+id/product_item_pic"
android:layout_width="150dp"
android:layout_height="150dp"
android:src="#drawable/ic_fastfood_24"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
Please help and I can answer any follow up questions the best I can, thanks!
In you .xml file, add this -
android:scaleType="fitXY"
It should work
Please inform me if this works
Related
Why doesn't textView21.SetLeftTopRightBottom(1,200,45, 275) change the size of a textview?
<TextView
android:id="#+id/textView21_id"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_x="22dp"
android:layout_y="105dp"
android:height="50dp"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text=""
android:textSize="30sp"
android:textColor="#000000"
android:background="#9999cc"
android:singleLine="false"/>
There's the activity_main.xml snippet. Is there something there which overrides the SetLeftTopRightBottom?
I am still trying to get two different but ordinary mobile phones (cell phones) to display a view the same.
pic of same app in two phones
You can see the left hand pic shows to below the grey '6:' textview and includes the 'Go' textview and all the right hand 5th-letter-in-the-word textview areas whereas the other pic doesn't.
I've figured out how to get each phone's display metrics
var metrics = Resources.DisplayMetrics;
gnumWidthDp = ConvertPixelsToDp(metrics.WidthPixels);
gnumHeightDp = ConvertPixelsToDp(metrics.HeightPixels);
I thought it would be easy to do the SetLeftTopRightBottom thing and set each textview in the right place.
Please can you tell me what I have missed? Thank you all.
In the official document, SetLeftTopRightBottom method is meant to be used in animations only as it applies this position and size for the view only temporary and it can be changed back at any time by the layout.
More information: https://developer.android.com/reference/android/view/View#setLeftTopRightBottom(int,%20int,%20int,%20int)
In addition, the size of the textview21 had been ensured in the xml. If you want to set the size of it dynamically, you need to use the LayoutParams. Such as:
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(300, 200);
//300 is width and 200 is height
textView.LayoutParameters = layoutParams;
I have a HashMap in which I stored images with Bitmap format. Now the problem is how do I get those images again?
In details,
Here in this hasmap, I stored my Bitmap image as an object.
ArrayList<HashMap<String,Object>> mImgList = new ArrayList<HashMap<String,Object>>();
Bitmap img = imgLoader.decodeSampledBitmapFactoryFromUrl(x,x,x,x);
HashMap<String, Object> map = new HashMap<String, Object>();
map.put(TAG_IMG, img);
map.put(TAG_NAME, name);
map.put(TAG_ID, cont_id);
mImgList.add(map);
I use this hashmap in the listview to diplay img and text, everything's fine.
But now I need to display some of those images in a ImageView, but I don't know how to get the image as those Bitmap in the HashMap is becoming an object.
I tried to use:
Bitmap bmp = mImgList.get(x).get(TAG_IMG);
but what i got is actualy an object not a bitmap. so how should i get my bitmap? or are there any other way I can display this picture on the alertdialog? thanks!
Turns out no one answered my question...But I end up converting bitmap into drawable so that I can save them into hashmap and get them when i want.
Bitmap bitmap = (Bitmap) mMap.get("bitmap_key_001");
I am having a strange problem. I scale an image and, while scaling works correctly, the image always gets clipped. I tried different scale types - things changed but I never could make it work.
Just to be clear, here's what I need to solve:
1. I have a HorizontalScrollView around the ImageView and a ScrollView around the HorizontalView.
2. I scroll around (using scrollTo of both scroll views) and, upon a certain event, zoom in.
3. What I'd like to happen is for the ImageView to scale around my current scroll position.
Here's the layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
android:overScrollMode="never">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
android:overScrollMode="never">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:scaleType="fitCenter" />
</HorizontalScrollView>
</ScrollView>
</FrameLayout>
And here's the scaling code (originalWidth/originalHeight are calculated at scale of 1; targetView points to the ImageView):
public synchronized void changeScale(float newScaleFactor) {
this.scaleFactor = Math.max(min_zoom, Math.min(newScaleFactor, max_zoom));
if (targetView != null && originalWidth > 0) {
int newWidth = (int)(originalWidth * scaleFactor);
int newHeight = (int)(originalHeight * scaleFactor);
onScaleChanged(targetView, scaleFactor, newWidth, newHeight);
}
}
public void onScaleChanged(View targetView, float scaleFactor, int newWidth, int newHeight) {
ViewGroup.LayoutParams layoutParams = targetView.getLayoutParams();
layoutParams.width = newWidth;
layoutParams.height = newHeight;
// This is needed to increase the pane size (rather than zoom within the initial layout)
targetView.setLayoutParams(layoutParams);
// Tell the system to recalculate the layout
targetView.requestLayout();
// This is needed to specify the center of scaling
HorizontalScrollView horizontalScrollView = (HorizontalScrollView)targetView.getParent();
ScrollView vertScrollView = (ScrollView)horizontalScrollView.getParent();
// ~~~ the pivot points are probably wrong
targetView.setPivotX(horizontalScrollView.getScrollX() * scaleFactor);
targetView.setPivotY(vertScrollView.getScrollY() * scaleFactor);
// This is needed for actual zooming
targetView.setScaleX(scaleFactor);
targetView.setScaleY(scaleFactor);
};
public void zoomIn(float scaleDelta) {
changeScale(scaleFactor + scaleDelta);
}
public void zoomOut(float scaleDelta) {
changeScale(scaleFactor - scaleDelta);
}
Question 1: How do I prevent clipping? I can't find the right combination of scaleType and layout resizing.
Question 2: When I use setScaleX/setScaleY, should my pivot be calculated after applying the new scale factor or does the renderer take care of that automatically?
After updating the scale you need to invalidate(), and requestLayout() the views.
targetView.invalidate();
targetView.requestLayout();
I usually calculate the scale differently for images. You could try to scale the image view using the MATRIX scale type. You will need to know the size of your bound DPI.
// Get the scaled DPI
int boundBoxInDp = getResources().getDisplayMetrics().densityDpi * scaleFactor
// Determine how much to scale: the dimension requiring less scaling is
// closer to its side. This way the image always stays inside your
// bound AND either x/y axis touches the bound but neither will go over.
float xScale = ((float) boundBoxInDp) / newWidth;
float yScale = ((float) boundBoxInDp) / newHeight;
float scale = (xScale <= yScale) ? xScale : yScale;
// scale using our calculated scale
targetView.setScaleX(scale);
targetView.setScaleY(scale);
As to your second question about the Pivot. That will probably need to be set to the center of the visible scroll area. The the scrollable area should be increased when you change the image size since you are using FIT_CENTER;
See this article for code that works quite well. I ditched my HorizontalScrollView and ScrollView and attached this PanAndZoomListener to my FrameLayout and from then on it was all rainbows and unicorns.
I tried to do the same thing as you, but without success. It would seem that you can scroll an ImageView without using HorizontalScrollView and ScrollView. I'm still unclear as to what makes it happen, but I'm leaning toward the use of the image matrix (as in, setImageMatrix on ImageView) or possibly the use of MarginLayoutParams. In looking at the Gallery source code from the picture Gallery available on the Android, I'm seeing heavy use of Matrix. Unfortunately, the documentation on this seems to be quite light in my estimation.
Other people have figured it out, so plug in the PanAndZoomListener and you're done. That's what I did.
I have an app that needs to dynamically align text views over certain locations on an image. The image is scaled to fit the view. Text entries are added by the user. I'm using a RelativeLayout and margins to properly position the text. All is good.
When the user rotates the screen, I save the text locations and bitmap using onRetainNonConfigurationInstance(). When the view is recreated, I add the views back into the RelativeLayout. Now, because the view is a different size, the scale of the image is different. To keep the text boxes in the same location, I have to account for that. I have all that code working except for one issue....
If I create a TextView and set the fontSize to a small size (e.g. <11px), the top of the text box is positioned where I want it to be but the text is aligned with a baseline as if it were 11px font. I don't know the scale factor in the onCreate method so I can't change the font size until after onMeasure and onLayout are called. I've tried forceLayout() and requestLayout() but nothing seems to fix the alignment problem.
Here is the layout:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="0dp"
>
<com.xyx.ScalableLayout
android:id="#+id/layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="0dp"
android:clickable="true"
android:gravity="top"
>
<com.xyx.ScaledImageView
android:id="#+id/formView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="0dp"
/>
<com.xyx.ScalableLayout>
</ScrollView>
A textView is added with the following code:
textView = new TextView(getContext());
textView.setPadding(0, 0, 0, 0);
textView.setSingleLine();
textView.setFocusableInTouchMode(false);
textView.setClickable(false);
textView.setGravity(Gravity.TOP);
textView.setText(entry.mText);
float fontSize = mImageView.mapSizeToView(entry.mPointSize);
textView.setTextSize(TypedValue.COMPLEX_UNIT_PT, fontSize);
params = new RelativeLayout.LayoutParams(
ViewGroup.MarginLayoutParams.WRAP_CONTENT,
ViewGroup.MarginLayoutParams.WRAP_CONTENT);
params.leftMargin = Math.round(viewLoc.x);
params.topMargin = Math.round(viewLoc.y);
addView(textView, params);
When ScaledImageView gets an onSizeChanged() callback, it sets the scale value and updates the font size and location of TextViews with the following code:
float fontSize = mImageView.mapSizeToView(entry.mPointSize);
textView.setTextSize(TypedValue.COMPLEX_UNIT_PT, fontSize);
PointF viewLoc = computeTopLeft(entry, entry.mTextView.getPaint());
params = (RelativeLayout.LayoutParams) textView.getLayoutParams();
params.leftMargin = Math.round(viewLoc.x);
params.topMargin = Math.round(viewLoc.y);
textView.setLayoutParams(params);
textView.forceLayout();
And finally, I do a
requestLayout() on the ScalableLayout
I know that's a lot of code but my problem is this. If I know the proper scale factor (used in mapSizeToView()) when I am creating the TextView and adding it to the screen everything works fine. If the value is incorrect, then nothing I can find will do a full recalculate that will get the TextView to be the same as if it were created with that font size. I believe it is tied to Android Layout structure which I generally understand. However, I don't understand why I can't get it to recompute from scratch (short of tearing down all the views and recreating them).
I'm developing an app on android and I am generating UI elements in a loop. But I need these elements to have an id with letters and numbers, for example "rl1" or "rl2". I was trying to use the method RelativeLayout.setId() but, that method only accepts int. Is there a way I can set an ID as I want without being limited to numbers?
Thanks.
Here is the code I am trying to make work.
for (int i=1; i < 10; i++)
{
//gets the frameview where the elements will be created.
String LinearLayoutId = "frameview1";
int resID = getResources().getIdentifier(LinearLayoutId, "id", "com.myapp.ERS");
LinearLayout linearLayout = (LinearLayout)findViewById(resID);
//creates the RelativeLayout that will hold the ImageIcon and the TextView
RelativeLayout rl = new RelativeLayout(this);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,40 );
rl.setLayoutParams(lp);
rl.setId("rl"); /// >>>> I would like here to set and ID of "rl1" for example.
rl.setBackgroundDrawable(getResources().getDrawable(R.drawable.bk36));
//creates the image icon within the layout at the left side
ImageView image = new ImageView(this);
lp = new RelativeLayout.LayoutParams(
40,RelativeLayout.LayoutParams.MATCH_PARENT );
image.setLayoutParams(lp);
String imageicon = "icon_"+i;
resID = getResources().getIdentifier(imageicon, "drawable", "com.myapp.ERS");
image.setImageDrawable(getResources().getDrawable(resID)); //sets the icon
rl.addView(image); //adds the ImageView to the relative layout
//creates the TextView within the layout with a 40 margin to the left
TextView tv = new TextView(this);
lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,RelativeLayout.LayoutParams.MATCH_PARENT );
lp.setMargins(40, 0, 0, 0);
tv.setLayoutParams(lp);
String textViewID = "tv"+i;
resID = getResources().getIdentifier(textViewID, "string", "com.myapp.ERS");
tv.setText(getResources().getString(resID));
tv.setTextColor(Color.BLACK);
tv.setTextSize(25);
rl.addView(tv);//adds the TextView to the relative layout
rl.setOnClickListener(mAddListener);
linearLayout.addView(rl);//adds the RelativeLayout to the LinearLayout
}
and then I have the OnCLickListener like this...
private OnClickListener mAddListener = new OnClickListener()
{
public void onClick(View v){
Intent intent;
Bundle bundle;
String id = getResources().getResourceEntryName(v.getId());
id = id.replaceAll("\\D+","");
int value = Integer.parseInt(id);
intent = new Intent(ERS.this, ShowInfo.class);
bundle = new Bundle();
bundle.putInt("key", value);
System.out.println(v.getId());
intent.putExtras(bundle);
startActivity(intent);
}
};
I have tried to set up numeric IDs, but then when I Look for them with:
String id = getResources().getResourceEntryName(v.getId());
It can't find them.
I had all of this in an xml file to begin with, but it was really long because there are about forty items in the list, and it was complicated for me to go and change a letter for example in all of them. I came up with this idea to generate them at runtime in a for loop. I am testing in the meantime with ten, but I can't get it to work.
If I am doing something incorrect, then pardon me, but I am new to this.
You may still find it easier to go back to XML layouts and use the R class to generate meaningful IDs. Although as you haven't included the original xml file you refer to at the end of the question, so I can only guess at the problem you had with it. It does seem to fit the bill though, and would allow you to create something along the lines of:
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:id="#+id/hellotextview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="Hi there"/>
The android:id="#+id/hellotextview" generates an id that can be used elsewhere in your project. In your java code you could access that specific TextView with something similar to:
TextView helloText = (TextView) findViewById(R.id.hellotextview);
The R.id.hellotextview is a int automatically generated when the project is built (in gen/R.java), but as you get to pick the name you can assign them something relevant to you and your project. So instead of trying to use strings values such as "rl1" and "rl2" that you mentioned, you could use R.id.rl1 and R.id.rl2.
As well as individual UI elements, you can also use the same technique for strings (in res/values/strings.xml), and other resources stored under the project's res/ folder, such as icons, media files, etc. In the case of strings you would access them getString(R.string.some_name_given_by_you);
See Accessing Resources at the Android Developers site for more info.
Why dont you try using SharedPreferences as an alternative in case you want to access the elements which you give some ID elsewhere in some other activity.