I am developing an Android application where an activity displays content in a scrollview. At the top of the content there is a placeholder for an image to be displayed. The image is downloaded from the Internet and may take a few seconds until it is ready to be displayed. The image placeholder is initially empty. When the image is downloaded, it is dynamically added to the placeholder.
Initially I had the following problem.
The user starts the activity and scrolls down
The image starts to download in the background. When available, it is added to the placeholder
When the image is added to the placeholder, the contents of the scrollview change and the user experience is disrupted by the unwanted scrolling that occurs
To fix this, I added code to adjust the scroll position once the image view is added to the placeholder. The problem with this is that a flickering is caused on the scrollview during the display-image and adjust-scrollview process. The reason is that the scrollBy function is called from a runnable. Calling scrollBy outside the runnable does not cause flickering but the scroll position is incorrect - the reason for this is that there is not enough time for the items on the scroll view to recalculate/measure their dimensions/heights.
Here is a sample application the illustrates this problem:
public class MainActivity extends AppCompatActivity {
ScrollView scrollView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scrollView = findViewById(R.id.scrollview);
startImageDownload();
simulateImageScroll();
}
private void simulateImageScroll() {
// scroll to the bottom of the scroll view
scrollView.post(new Runnable() {
#Override
public void run() {
scrollView.scrollTo(0, scrollView.getMaxScrollAmount());
}
});
}
private void startImageDownload() {
Handler handler = new Handler(getMainLooper());
// simulate a delay for the image download to illustrate the flashing problem in the scrollview
handler.postDelayed(new Runnable() {
#Override
public void run() {
displayImage("");
}
}, 2000);
}
// when the image is downloaded we add it to the image container
private void displayImage(String imageFilename) {
// dynamically create an image and add it to the image container layout
RelativeLayout container = findViewById(R.id.imageContainer);
ImageView img = new ImageView(this);
// image should be loaded from the given filename - for now use a solid background and fixed height
img.setBackgroundColor(Color.BLUE);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, 500);
container.addView(img, params);
adjustScrolling(container);
}
private void adjustScrolling(RelativeLayout container) {
// adjust scroll if the image is loaded before the current content
if (scrollView.getScrollY() > container.getTop()) {
container.measure(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
final int amountToScroll = container.getMeasuredHeight();
// the following does not cause flickering but scrolls to the wrong position
//scrollView.scrollBy(0, amountToScroll);
// adjust the scrollview so that it keeps the current view unchanged
scrollView.post(new Runnable() {
#Override
public void run() {
// this causes flickering but scrolls to the correct position
scrollView.scrollBy(0, amountToScroll);
}
});
}
}
}
And here is the layout file:
<ScrollView
android:id="#+id/scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/imageContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:background="#aa0000" >
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:background="#aa0000" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1"
android:textColor="#ffffff"
android:textSize="128dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:background="#aa0000" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2"
android:textColor="#ffffff"
android:textSize="128dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:background="#aa0000" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="3"
android:textColor="#ffffff"
android:textSize="128dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:background="#aa0000" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="4"
android:textColor="#ffffff"
android:textSize="128dp"/>
</RelativeLayout>
</LinearLayout>
</ScrollView>
Any ideas on how to fix this problem?
Edited:
Currently, your layout is flickering, because adding blue view cause redraw layout (and scroll). So scroll occurred once, and next you scrolled to the position you want. That's the second moving.
To solve this problem, you need to know how android draws view.
https://developer.android.com/guide/topics/ui/how-android-draws.html
Simply, onMeasure() - onLayout() - onDraw(). And you can add your layout code between onLayout() and onDraw(), by ViewTreeObserver().addOnGlobalLayoutListener().
https://developer.android.com/reference/android/view/ViewTreeObserver.OnGlobalLayoutListener.html
ps: I still recommend using nice and lovely image library, Picasso.
Fixed code is: Set scroll before draw() called. By this, you can draw only once.
public class MainActivity extends AppCompatActivity {
ScrollView scrollView;
int amountToScroll = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scrollView = findViewById(R.id.scrollview);
scrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
scrollView.scrollBy(0, amountToScroll);
amountToScroll = 0;
}
});
startImageDownload();
simulateImageScroll();
}
private void simulateImageScroll() {
// scroll to the bottom of the scroll view
scrollView.post(new Runnable() {
#Override
public void run() {
scrollView.scrollTo(0, scrollView.getMaxScrollAmount());
}
});
}
private void startImageDownload() {
Handler handler = new Handler(getMainLooper());
// simulate a delay for the image download to illustrate the flashing problem in the scrollview
handler.postDelayed(new Runnable() {
#Override
public void run() {
displayImage("");
}
}, 2000);
}
// when the image is downloaded we add it to the image container
private void displayImage(String imageFilename) {
// dynamically create an image and add it to the image container layout
RelativeLayout container = findViewById(R.id.imageContainer);
ImageView img = new ImageView(this);
// image should be loaded from the given filename - for now use a solid background and fixed height
img.setBackgroundColor(Color.BLUE);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, 500);
container.addView(img, params);
adjustScrolling(container);
}
private void adjustScrolling(RelativeLayout container) {
// adjust scroll if the image is loaded before the current content
if (scrollView.getScrollY() > container.getTop()) {
container.measure(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
amountToScroll = container.getMeasuredHeight();
}
}
}
I strongly recommend using Picasso. http://square.github.io/picasso/
This one line will fix all of your problem.
Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
You can load your local image file or network image (url) into your imageView.
In your case, remove both startImageDownload() and simulateImageScroll(), and on onResume(), call displayImage().
Fixed displayImage():
private void displayImage(String imageFilename) {
// dynamically create an image and add it to the image container layout
RelativeLayout container = findViewById(R.id.imageContainer);
ImageView img = new ImageView(this);
// image should be loaded from the given filename - for now use a solid background and fixed height
img.setBackgroundColor(Color.BLUE);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, 500);
container.addView(img, params);
Picasso.with(this).load(imageFilename).into(img);
adjustScrolling(container);
}
Or, if you want to solve this problem directly for academic reasons,
Do not adjust your scroll. It seems that it is not a real solution to use scrollBy to fix your problem. The real cause is the code that cause the UI to redraw. May be calling invalidate() or something like that.
Adding ImageView programmatically is not a good idea. Because your RecyclerView or ViewHolder of ListView cannot reuse the view, so it cause degrade performance. If you can avoid it, do that. (eg. use xml)
It seems that adding your ImageView to imageContainer is real problem. imageContainer has android:layout_height="wrap_content" property, and this means it has no fixed height, it depends on it's own child. Try to change to fixed value, for example: android:layout_height="500dp"
Well first if it's a single image on top then you don't have to create imageview dynamically just use it inside your XML file without Relative-layout. set to an default image. Use Image-View with adjustViewBounds="true" and scaleType="fitCenter" then you don't have to worry about the image scaling.
<ImageView
android:id="#id/img"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitCenter" />
you can use Picasso http://square.github.io/picasso/ library as suggested by "Stanley Kou" for loading the image.
My Suggestion is to use Progress Bar, Start the Progress bar when image starts downloading and hide it once the image load is complete then let the user see the activity.
<ProgressBar
android:id="#+id/indeterminateBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
For more details, please check -
https://developer.android.com/reference/android/widget/ProgressBar.html
Related
I have several expandable layouts in my Android App. When I click to expand a layout, the layout disapear outside the screen, and I have to manual scroll down to make it visible. How can I make the ScrollView automatically scroll down to make the clicked layout visible?
I tried using scrollView.scrollTo(0, textID.getBottom()); to scroll to the bottom of the layout element, but without luck.
Java:
expandableLayout1 = root.findViewById(R.id.expandable_layout1);
button = (LinearLayout)root.findViewById(R.id.box_header);
button.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
if (expandableLayout1.isExpanded()) {
expandableLayout1.collapse();
} else {
expandableLayout1.expand();
scrollView.scrollTo(0, textID.getBottom());
}
}
});
xml:
<LinearLayout
android:id="#+id/box"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/box_header"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="#+id/textID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="title"
android:textColor="#ffffff"
android:textSize="16sp"/>
</LinearLayout>
<net.cachapa.expandablelayout.ExpandableLayout
android:id="#+id/expandable_layout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:el_duration="1000"
app:el_expanded="false"
app:el_parallax="0.5">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="some text"
android:textColor="#ffffff"
android:textSize="12sp"/>
</net.cachapa.expandablelayout.ExpandableLayout>
</LinearLayout>
The problem you are facing is that the ExpandableLayout doesn't have time to finish opening before ScrollView already ends up scrolling to the bottom of it. So what ends up happening is that the ScrollView Scrolls to the bottom of the ExpandableLayout which hasn't fully opened yet. What you need to do is add a delay between the Layout opening and the ScrollView starting it's scroll function. Here is the code you need, I would try adjusting the milliseconds, you could probably drop them down below 1000 but not by much, still it's up to you to troubleshoot it a bit to make it just a tad bit faster and smoother. Also try using smoothScrollTo instead of scrollTo.
expandableLayout1 = root.findViewById(R.id.expandable_layout1);
button = (LinearLayout)root.findViewById(R.id.box_header);
button.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
if (expandableLayout1.isExpanded()) {
expandableLayout1.collapse();
} else {
expandableLayout1.expand();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
scrollView.post(new Runnable() {
#Override
public void run() {
scrollView.scrollTo(0, textID.getBottom());
}
});
}
}, 1000 ); // time in milliseconds
}
}
});
And here is the code that I added in it's raw form, might help you understand it a bit easier.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// do something
}
}, 1000 ); // time in milliseconds
For some reason when I set the x coordinate to screen_width - image_width, the image is displayed off the screen. The same scenario occurs with the y coordinate. Here is my code.
public class MainActivity extends AppCompatActivity {
ImageView image;
float height;
float width;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
height = displayMetrics.heightPixels;
width = displayMetrics.widthPixels;
image.setImageResource(R.drawable.pigeon);
image.setX(width - image.getMeasuredWidth());
In this case the image, which is a pigeon, is not displayed on the screen. And I expect it to be displayed so that the right border of the pigeon touches the right border of the screen.
Edit: It's not that I just want to position the image and be done with it. I want to be able to move the image to precise coordinates while the app is running, such as when a mouse click occurs.
One way to align the image right is to use the XML layout. This is the easiest method.
Assuming you have an ImageView inside a RelativeLayout you can use the `layout_alignParentRight' attribute as follows:
<?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:id="#+id/view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
tools:context=".MainActivity">
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#string/image_name"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
/>
</RelativeLayout>
The layout_alignParentEnd attribute is an alternative for layout_alignParentRight for right to left language script. For a LinearLayout you can use layout_gravity attribute. Also, ensure that your ImageView is wrap_content and not match_parent in which case the image will expand to fill the entire ImageView.
If you want to do it programmatically, you can do it in the following manner:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.imageView);
imageView.setImageResource(R.drawable.pigeon);
RelativeLayout.LayoutParams params = new
RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
imageView.setLayoutParams(params);
}
Here we are aligning the child view of RelativeLayout right by adding the align right rule and then setting that layout parameter for the Image View. This can also be done for LinearLayout using layout_gravity feature.
I have tested this code for a sample image. Hope this solves your problem.
I have a custom view that extends SurfaceView overlaying the rest of my interface, it works on emulators and when the debugger is connected on my phone, but but when the phone is running on battery the view never clears.
public class CustomView extends SurfaceView {
private final Paint paint;
private final SurfaceHolder holder;
private final Context context;
private float strokeWidth = 4;
private boolean canvasAlreadyLocked = false;
public CustomView(Context viewContext, AttributeSet attrs)
{
super(viewContext, attrs);
Log.i("CustomView", "CustomView create context & attrs");
holder = getHolder();
context = viewContext;
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(strokeWidth);
drawLine();
setZOrderOnTop(true);
holder.setFormat(PixelFormat.TRANSPARENT);
}
public void resume() {
Log.i("CustomView", "Resume the customview display.");
setZOrderOnTop(true);
holder.setFormat(PixelFormat.TRANSPARENT);
}
#Override
public void onAttachedToWindow(){
super.onAttachedToWindow();
setZOrderOnTop(true);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
protected void drawLine() {
if (!canvasAlreadyLocked) {
invalidate();
if (holder.getSurface().isValid()) {
try {
final Canvas canvas = holder.lockCanvas();
canvasAlreadyLocked = true;
if (canvas != null) {
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
paint.setColor(Color.BLACK);
paint.setStrokeWidth(strokeWidth * 2);
canvas.drawLine(0, getY(), getWidth(), getY(), paint);
paint.setColor(Color.WHITE);
paint.setStrokeWidth(strokeWidth);
canvas.drawLine(0, getY(), getWidth(), getY(), paint);
holder.unlockCanvasAndPost(canvas);
canvasAlreadyLocked = false;
}
}
catch (IllegalArgumentException iae)
{
Log.w("CustomView", "Exception trying to lock canvas: "+iae.getMessage());
Log.getStackTraceString(iae);
}
}
}
}
private float getY() {
getHeight()/2;
}
}
I'm aware that some of the calls here are redundant - that is mostly the legacy of trying lots of different things to try to make it work. You will notice that I have already done everything recommended in this answer.
The layout works like this:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.custom.CustomViewApp">
<FrameLayout
android:id="#+id/control"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true">
<com.custom.AutoFitTextureView
android:id="#+id/texture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" />
<ImageButton
android:id="#+id/gpsNotification"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/gps_unfixed"
android:layout_gravity="right"
android:tint="#color/gps_unfixed"
android:background="#null" />
<ProgressBar
android:id="#+id/camera_spinner"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:gravity="center"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:visibility="invisible"
/>
<com.custom.CustomView
android:id="#+id/custom_view"
android:background="#color/transparent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" />
</FrameLayout>
</FrameLayout>
This is pulled in from a ViewFragment:
#Override
public void onViewCreated(final View view, Bundle savedInstanceState) {
mTextureView = (AutoFitTextureView) view.findViewById(R.id.texture);
gpsNotification = (ImageButton) view.findViewById(R.id.gpsNotification);
customView = (CustomView) view.findViewById(R.id.custom_view);
spinner = (ProgressBar) view.findViewById(R.id.camera_spinner);
spinner.setVisibility(VISIBLE);
}
I have tried to simplify this as far as I can and obviously there is a lot more happening in this scenario, but hopefully this is enough to indicate where the problem might be coming from.
The AutoFitTextureView is displaying the view from the camera.
When I run it in an emulator, everything displays as expected,
regardless of the battery settings.
When I run it on my phone connected by USB everything displays as expected.
When I run it on my phone disconnected, the view will usually, but not always, show as plain black - the AutoFitTextureView is completely obscured, but the line on the CustomView is drawn. The other components are visible, which leads me to suspect there is a problem with when or how I call setZOrderOnTop().
If I hit a breakpoint in the fragment and set the visibility of the CustomView to INVISIBLE I can immediately see everything else, but as you might expect I lose the overlay. Manually calling setZOrderOnTop at that point doesn't seem to change anything.
When it is running correctly, I can examine the structure with the Layout Inspector tool, but when the SurfaceView is opaque the Layout Inspector raises an Unexpected Error: Empty View Hierarchy message. I haven't been able to locate a corresponding error message in Logcat.
How do I ensure my SurfaceView-derived View is always transparent? If I can't guarantee that, is there any way I can test whether it currently is transparent so that I can intercede if it is not?
I think I have now solved this and the problem was that I was trying to put a SurfaceView derived type over a TextureView derived type. Switching out the AutofitTextureView for another SurfaceView showing the camera preview seems to have done the trick.
I am absolutly new in Android development and I have the followind doubt.
I have to draw images one next to each other into a Canvas object.
So let to do an example of what I neeed:
Into the /res/drawable/ folder of my project I have this icon (I have resized it before put it into my project but I think that this is not so important):
So I have to put 3 of these icon one next to each other into a specific ImageView of my activity view (adding some white space between an image and the next one).
So I have done something like this:
1) This is the code of my fragment_screen_slide.xml file that represent the layout where these images have to be placed:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="0dp">
<ImageView
android:id="#+id/imageView1"
android:layout_width="fill_parent"
android:scaleType="fitXY"
android:layout_height="250dp" />
<TextView android:id="#android:id/text1"
style="#style/pastaTitleTextStyle" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0px"
android:layout_weight="1"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
style="#style/HeaderTextStyle"
android:text="Difficoltà :" />
<ImageView
android:id="#+id/starContainer"
android:layout_width="fill_parent"
android:scaleType="fitXY"
android:layout_height="250dp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
In particular these images have to be placed into this ImageView contained in the previous code snippet:
<ImageView
android:id="#+id/starContainer"
android:layout_width="fill_parent"
android:scaleType="fitXY"
android:layout_height="250dp" />
Here I have a first doubt because Androi Studio report an error on this line:
android:id="#+id/starContainer"
The reported error is a red underline on the # and when I pass the mouse pointer on it I can read the following error message:
<interface declaration>, <perceable declaration>, AidToken.import or AidTokenTye.package expected, got '#'
It seems strange to me because I am only creatin an id for the ImageView and because I have not problem when Gradle build the project.
Then, into the Java code that actually put the images into the previous ImageView I have done something like this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
System.out.println("PAGE NUMBER: "+ mPageNumber + 1);
// Create the Canvas where the images are putted:
Canvas difficultyCanvas = creaImgDifficulty();
switch (mPageNumber + 1) {
case 1:
imgSlideView.setImageResource(R.drawable.carbonara);
((TextView) rootView.findViewById(android.R.id.text1)).setText(getString(R.string.carbonara));
difficultyCanvas = creaImgDifficulty();
ImageView starContainer = (ImageView) rootView.findViewById(R.id.starContainer);
starContainer.draw(difficultyCanvas);
break;
// OTHER CASES
}
private Canvas creaImgDifficulty() {
Canvas canvas;
Bitmap chefHatOk = BitmapFactory.decodeResource(getResources(), R.star);
Bitmap output = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
canvas = new Canvas(output);
int space = 10; // the space between images
for(int i = 0; i < 3; i++) {
canvas.drawBitmap(chefHatOk, i * (chefHatOk.getWidth() + space), 0, null);
}
return canvas;
}
}
So, as you can see in the previous code sippet, when the view is created first I create a new Canvas object (that contains the repeated images) calling the creaImgDifficulty() and then I try to draw this Canvas object into the previous ImageView having id=starContainer.
The creaImgDifficulty() create the Canvas object and draw the bitmap on it 3 times.
I obtain no error when I run the application but the images is not displayed into my ImageView.
Why? What is wrong? What am I missing? How can I try to solve this issue?
XML cannot contain capitals. Switch your ID line to:
android:id="#+id/star_container"
Then change your java file references to match.
By default HorizontalScrollView scrolls from Left to Right but I want to scroll from Right to Left.
How to do this? Any help will be appreciated.
You can scroll it to the right edge of your scroll view in your code with something like this:
scrollView.postDelayed(new Runnable() {
public void run() {
scrollView.fullScroll(HorizontalScrollView.FOCUS_RIGHT);
}
}, 100L);
Related Q and A is https://stackoverflow.com/a/4720563/2511775
add layout_gravity RIGHT its helpful when items dose not wrap hole with
<HorizontalScrollView
android:id="#+id/scrollPartition"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none">
<LinearLayout
android:id="#+id/lytPartition"
android:layout_gravity="right"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:scrollbars="none">
</LinearLayout>
</HorizontalScrollView>
and in code need to scroll to the end of list
findViewById(R.id.scrollPartition).post(new Runnable() {
#Override
public void run() {
((HorizontalScrollView) findViewById(R.id.scrollPartition)).fullScroll(View.FOCUS_RIGHT);
}
});
to set layout_gravity programmatically use this :
HorizontalScrollView scrollView = new HorizontalScrollView(context);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.gravity = Gravity.RIGHT;
scrollView.setLayoutParams(layoutParams);
Add this attribute to HorizontalScrollView :
android:layoutDirection="rtl"
(not good solution)