Android ScrollView scrolling - android

I'm working on a project where I have a ScrollView which contains a linearlayout.
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#9e9e9e"
android:layout_weight="2"
android:id="#+id/scrollview_llChatContainer"
android:layout_above="#+id/relativeLayout">
<LinearLayout
android:id="#+id/llChatContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:orientation="vertical"
android:background="#cccccc">
</LinearLayout>
</ScrollView>
I'm inflating this linearlayout in my code. The last result looks more like a listView. Here is how I'm inflating the LinearLayout.
public void populateMessages(List<Message> messagesList){
inflater.inflate(R.layout.inc_message_layout, llChatContainer, false);
imageLoader.displayImage(message.imageuser, (ImageView)messageLayout.findViewById(R.id.imageView));
}
if(!message.image.equalsIgnoreCase("")){
imageLoader.displayImage(message.image, (ImageView)messageLayout.findViewById(R.id.rivMsgImageN));
}
TextView tv = (TextView)messageLayout.findViewById(R.id.tvMsgTextN);
tv.setText(message.text);
llChatContainer.addView(messageLayout);
}
}
Now when the list is populated, I want the scrollView to scroll to the bottom of the LinearLayout. I have tried two of the ways I found.
scroller.post(new Runnable() {
public void run() {
scroller.fullScroll(ScrollView.FOCUS_DOWN);
}
});
scroller.post(new Runnable() {
public void run() {
scroller.scrollTo(0,scroller.getBottom());
}
});
None of the above mentioned solution is working for me. Linearlayout gets populated as expected but the scrollview doesn't even scroll a bit.
Is there any other work-around to get this done?
Thanks.

this is caused by time problem , try to scroll with a little delay , use this code
scroller.postDelayed(new Runnable() {
public void run() {
scroller.fullScroll(ScrollView.FOCUS_DOWN);
}
}, 10L);

Use scroller.scrollTo(0,linearlayout.getBottom()); or scroller.scrollTo(0,linearlayout.getHeight()); after populateMessages() called. Child of the ScrollView is changing it's value not the ScrollView itself.

Related

Start and end the horizontal scrollview from center of the screen

I need to start and end the content inside the Horizontal scrollview, like we had in Gallery (deprecated) widget. Contents inside the Horizontal scrollview should start from the center of the screen, and while scrolling, it should move to left from the center, the same as Gallery.
I have few hundred images, populated dynamically in the linearlayout inside the Horizontal scrollview. I acheived to auto scroll the horizontal scrollview with the time delay of one second. But I need to start the content from center and end in center.
public class ImageGalleryScrollActivity
extends AppCompatActivity {
HorizontalScrollView horizontalScrollView;
int maxCount=59;
Handler mHandler = new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
horizontalScrollView.smoothScrollBy(maxCount, 0);
mHandler.sendMessageDelayed(new Message(), 1000);
return false;
}
});
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.horizontal_scroll_activity);
horizontalScrollView=(HorizontalScrollView)findViewById(R.id.horizontalView);
mHandler.sendMessageDelayed(new Message(), 1000);
}
}
layout file:
<?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="match_parent">
<HorizontalScrollView
android:id="#+id/horizontalView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:fillViewport="true">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
</LinearLayout>
</HorizontalScrollView>
</RelativeLayout>
You could combine left/right padding each equal to half the screen width with the android:clipToPadding="false" attribute on your scrollview.
Since you won't know how much padding you'll need until runtime, you'll have to set the padding in Java. Put this in your onCreate():
scrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int padding = getResources().getDisplayMetrics().widthPixels / 2;
scrollView.setPadding(padding, 0, padding, 0);
scrollView.setClipToPadding(false);
}
});

Exception in Scrollview

In my android application, I'm facing a IllegalStateException. I can't reproduce this exception later. This is the stacktrace
Non-fatal Exception: java.lang.IllegalStateException: ScrollView can host only one direct child
at android.widget.ScrollView.addView(ScrollView.java:397)
at android.support.design.widget.BaseTransientBottomBar.showView(BaseTransientBottomBar.java:436)
at android.support.design.widget.BaseTransientBottomBar$1.handleMessage(BaseTransientBottomBar.java:178)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5679)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
at dalvik.system.NativeStart.main(NativeStart.java)
Anyone please help me!
I examined the question carefully, and I logically found that it is related to showing Snackbar on a fragment or activity, taken as a reference in another class as global object, when it is invalidated in onStop(), onDestroy() life cycle callback stage respectively:
https://stackoverflow.com/a/52019719/787399
Inside your ScrollView you have to host a child (e.g. a Linear Layout) which at it's time will host all the UI elements from that scrollview. You can't have, for example, 2 textviews added directly to a ScrollView. You need to have something to hold those UI elements inside the scrollview.
In ScrollView you can have only one View (in View I mean TextView, Button and cetera, but ViewGroup is child of View too) or ViewGroup. So if you have multiple Views put them in a proper ViewGroup and it will work fine.
Scrollview can only have one direct child
example:
This is valid-->
ScrollView
LinearLayout
Other Views
....
....
LinearLayout
ScrollView
This is not-->
ScrollView
LinearLayout
Other Views
....
....
LinearLayout
LinearLayout
Other Views
....
....
LinearLayout
ScrollView
I got the same issue. and I have reproduced using the below steps.
Step 1: make you Fragment Or Activity Layout with a parent of Scrollview.
Step 2: show Snackbar in onPause(), onStop(), onDestroy() like belove.
#Override
public void onPause() {
super.onPause();
Snackbar.make(button, "onPause", Snackbar.LENGTH_LONG).show();
}
#Override
public void onStop() {
super.onPause();
Snackbar.make(button, "onStop", Snackbar.LENGTH_LONG).show();
}
#Override
public void onDestroy() {
super.onDestroy();
Snackbar.make(button, "onDestroy", Snackbar.LENGTH_LONG).show();
}
Now run an app and check in logcat. when you click on back button you will get same error mention in question.
Solution:
make a common Snackbar like below.
#Override
public void onPause() {
super.onPause();
showSnackbar("onPause");
}
#Override
public void onStop() {
super.onPause();
showSnackbar("onStop");
}
#Override
public void onDestroy() {
super.onDestroy();
showSnackbar("onDestroy");
}
private void showSnackbar(String message) {
if (isValidContext(getActivity())) {
Snackbar.make(btnConsume, message, Snackbar.LENGTH_LONG).show();
}
}
public static boolean isValidContext(final Context context) {
if (context == null) {
return false;
}
if (context instanceof Activity) {
final Activity activity = (Activity) context;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
return !activity.isDestroyed() && !activity.isFinishing();
} else {
return !activity.isFinishing();
}
}
return true;
}
ScrollView will not accept many child's, Use only one Layout inside ScrollView like LinearLayout, RelativeLayout,FrameLayout or ConstraintLayout(Based on your needs)and then add all your child's.
See this for your reference
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
//Add your Views here
</android.support.constraint.ConstraintLayout>
</ScrollView>
Scroll view allow only one child directly like below :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<!--Here scroll view allow only one direct child-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!--Here your other xml code-->
</LinearLayout>
</ScrollView>
</LinearLayout>

Auto-Scroll ScrollView

I have a ScrollView with a TextView inside of it. I want to make sure that the app automatically scrolls down to the bottom each time text is entered into the TextView.
<ScrollView
android:id="#+id/textScroll"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/gridLayout"
android:layout_marginBottom="100dp"
android:fillViewport="true">
<TextView
android:id="#+id/numerTV"
android:layout_width="match_parent"
android:layout_height="70dp"
android:textSize="60sp"/>
</ScrollView>
So this is the .xml file. I have tried a lot of different solutions that I've found around here:
textScroll.post(new Runnable() {
#Override
public void run() {
textScroll.scrollTo(0, textScroll.getBottom());
//textScroll.post(new Runnable() {
//public void run() {
// textScroll.fullScroll(View.FOCUS_DOWN);
// }
// });
Log.d("Scroll","Scrolling");
}
});
Also tried to set autoscroll via xml but nothing works.
Any ideas what I'm doing wrong? How come the "solution" above works for so many but not for me?
Help much appreciated!
You can make your ScrollView move to the last position by using smoothScrollTo(x,y).
Then, you can get the arguments from the ScrollView
ScrollView sv = (ScrollView) findViewById(R.id.textScroll);
sv.smoothScrollTo(sv.getX(), sv.getY());

what is root layout in XML?

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rootLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="wrap_content"
android:layout_height="80dp"
android:scrollbars="none"
android:layout_x="0dp"
android:layout_y="0dp"
android:fillViewport="true" >
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="0dp"
android:layout_y="0dp"
android:src="#drawable/background" />
</LinearLayout>
</ScrollView>
</LinearLayout>
this is my xml file .which is pity much simple. My intention is to increase height of scroll view dynamically and the image (which is with the scroll view) view will be shown gradually.so how can i do that and What is rootLayout here and How i call rootLayout from my code ??
final Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
runOnUiThread(new Runnable()
{
public void run() {
secondCounter++;
yourNewHeight += 10;
sv.getLayoutParams().height = yourNewHeight;
LinearLayout root = (LinearLayout) findViewById(R.id.rootLayout);
root.invalidate();
Log.v("", "" +sv.getLayoutParams().height);
if(secondCounter == 20){
timer.cancel();
}
}
});
}
}, delay, period);
this is my code in java file.But its not working . guys can you help me out..!!!
The root of this layout is the AbsoluteLayout.
You can obtain a reference to this root View together with all of its children in your Activity using a call like:
mRootView = ((ViewGroup)findViewById(R.id.rootLayout));
Note that AbsoluteLaoyut is long depreciated and you will probably want to replace it with an alternative ViewGroup, such as a LinearLayout, RelativeLayout, etc. depending on the rest of your layout and how you want to do things.
If you've inflated your XML appropriately in code (ie called setContentView()) you should be able to reference rootLayout using:
AbsoluteLayout root = (AbsoluteLayout) findViewById(R.id.rootLayout);
Though if you're just trying to increase the height of the ScrollView, it makes more sense to directly call:
ScrollView scroll = (ScrollView) findViewById(R.id.scrollView1);
And as above, you should probably use a RelativeLayout or LinearLayout rather than an AbsoluteLayout.
Since ScrollView can only have one Child within it, you can use ScrollView itself as your root element with a LinearLayout as a direct and only child to it, inside which u can add any views you want.
And AbsoluteLayout is deprecated, and I'd recommend not to use it

Why HorizontalScrollView not scroll in HTCDesire 2.2 but only on simulator?

I am using a HorizentalScrollView in a view. I add TextView at runtime. I use horView.smoothScrollTo(x,y); It works fine for simulator. But it doesn't scroll at HTCDesire 2.2 ? any idea? here my code.
horView.smoothScrollTo(num, 0);
<HorizontalScrollView
android:id="#+id/cate_head"
android:scrollbars="none"
android:foregroundGravity="fill_horizontal"
android:layout_width="fill_parent"
android:paddingTop="6dip"
android:background="#drawable/slider_background"
android:focusable="true"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/cate_head_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip">
</LinearLayout>
</HorizontalScrollView>
At the end I found solution. I was calling smoothScrollTo(x,y) at the end of on create.(where else I can put that?) problem was that at the time of initializing there was not size or length found(But it should not be, because I have put all the data in that).
So call postDealy() with a delay of 50 sec. It works for me. Here is that. I put it at the end of onCreate();
May b anyone else have a batter solution...
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
horView.smoothScrollTo((scrollAmount), 0);
}
}, 50);
You can use View.post to avoid depending on timing.
horView.post(new Runnable() {
public void run() {
horView.smoothScrollTo((scrollAmount), 0);
}
});
This gets executed right after the view has been attached to the screen.

Categories

Resources