Zxing scanner Camera zoom - java

I've been trying to solve the problem for 3 days, but I still have not found the answer.
I want to add a ZOOM to the camera while scanning the qrcode through the Zxing scanner.
build.gradle:
implementation 'me.dm7.barcodescanner:zxing:1.9.8'
Xml:
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
ScannerFragment:
#Override
public void onResume() {
super.onResume();
activateScanner();
}
private ViewGroup contentFrame;
private ZXingScannerView zXingScannerView;
private void activateScanner() {
if(zXingScannerView != null) {
if(zXingScannerView.getParent()!=null) {
((ViewGroup)
zXingScannerView.getParent()).removeView(zXingScannerView); // to
prevent crush on re adding view
}
contentFrame.addView(zXingScannerView);
if(zXingScannerView.isActivated()) {
zXingScannerView.stopCamera();
}
zXingScannerView.startCamera(camId);
zXingScannerView.setFlash(isFlash);
//zXingScannerView.setAutoFocus(isAutoFocus);
}
}
I added SeekBar And with it I want to control the zoom of the camera.
private Camera cameraZoom;
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
try {
Camera.Parameters parameters = cameraZoom.getParameters();
}
catch (NullPointerException e) {
Log.d("NullP",e.getMessage());
}
}
LOG:
D/NullP: Attempt to invoke virtual method 'android.hardware.Camera$Parameters android.hardware.Camera.getParameters()' on a null object reference
I tried to do this using the code above, but there were only errors
Please tell me how to do this.

if(cameraZoom == null){
cameraZoom = Camera.open();
}
This line is missing in your code.

You cannot open the camera when Zxing is opening the camera, so cameraZoom.getParameters () (cameraZoom is null).

Related

Using Street View VR in my app

I'm using Android Studio and trying to show some chosen Street View paths in VR. I already have Street View running well and now I'm trying to show it in VR.
I have put the com.google.vr.sdk.widgets.pano.VrPanoramaView in the layout and, inside onCreate in my class, referenced it to a VrPanoramaView variable through findViewById. Now I'm trying to show an image calling a method which I've defined in this class, loadPanoImage. This method loads an image from the storage and shows it through loadImageFromBitmap.
The problem is that it isn't able to show anything, even though I've followed a guide and I've done everything as showed. I've even tryed calling it in different parts of the code (before doing any other action, on clicking a button, before and after showing streetview) but I can't understand why it isn't working and how will I be able to use it to show images taken from StreetView (I don't know if I will be able to do it dinamically or I should download them and put them in the storage).
I'm putting part of the code for reference:
public class VrExperience extends FragmentActivity {
Button buttonCitta;
Button buttonMare;
Button buttonMontagna;
TextView titleTextView;
// George St, Sydney
private static final LatLng SYDNEY = new LatLng(-33.87365, 151.20689);
// LatLng with no panorama
private static final LatLng INVALID = new LatLng(-45.125783, 151.276417);
//VrPanoramaView is inserted in the layout
private VrPanoramaView panoWidgetView;
//StreetViewPanorama is another class in my project which shows Street View
private StreetViewPanorama mStreetViewPanorama;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_vrexperiences);
panoWidgetView = (VrPanoramaView) findViewById(R.id.pano_view);
panoWidgetView.setEventListener(new VrPanoramaEventListener());
//download image and show it, but it doesn't show anything
loadPanoImage();
titleTextView = (TextView) findViewById(R.id.titleTextView);
buttonCitta = (Button) findViewById(R.id.buttonCitta);
buttonCitta.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!checkReady()) {
return;
}
titleTextView.setVisibility(View.GONE);
buttonCitta.setVisibility(View.GONE);
buttonMare.setVisibility(View.GONE);
buttonMontagna.setVisibility(View.GONE);
loadPanoImage(); //it doesn't show anything
mStreetViewPanorama.setPosition(SYDNEY);
loadPanoImage(); //it doesn't show anything
}
}};
//code for buttonMontagna and buttonMare as well, it's identical
SupportStreetViewPanoramaFragment streetViewPanoramaFragment =
(SupportStreetViewPanoramaFragment)
getSupportFragmentManager().findFragmentById(R.id.streetviewpanorama);
streetViewPanoramaFragment.getStreetViewPanoramaAsync(
new OnStreetViewPanoramaReadyCallback() {
#Override
public void onStreetViewPanoramaReady(StreetViewPanorama panorama) {
mStreetViewPanorama = panorama;
// Only set the panorama to INVALID on startup (when no panoramas have been
// loaded which is when the savedInstanceState is null).
if (savedInstanceState == null) {
mStreetViewPanorama.setPosition(INVALID);
}
}
});
}
/**
* When the panorama is not ready the PanoramaView cannot be used. This should be called on
* all entry points that call methods on the Panorama API.
*/
private boolean checkReady() {
if (mStreetViewPanorama == null)
return false;
return true;
}
/**
* Called when the Animate To Invalid button is clicked.
*/
public void onGoToInvalid(View view) {
if (!checkReady()) {
return;
}
mStreetViewPanorama.setPosition(INVALID);
}
//retrieves image from the assets folder and loads it into the VrPanoramaView
private void loadPanoImage() {
VrPanoramaView.Options options = new VrPanoramaView.Options();
InputStream inputStream = null;
AssetManager assetManager = getAssets();
try {
inputStream = assetManager.open("demo2.jpg");
options.inputType = VrPanoramaView.Options.TYPE_MONO;
panoWidgetView.loadImageFromBitmap(
BitmapFactory.decodeStream(inputStream), options
);
inputStream.close();
} catch (IOException e) {
Log.e("Fail", "Exception in loadPanoImage" + e.getMessage());
}
}
#Override
protected void onPause() {
panoWidgetView.pauseRendering();
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
panoWidgetView.resumeRendering();
}
#Override
protected void onDestroy() {
panoWidgetView.shutdown();
super.onDestroy();
}
}
This is my layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/vrExperienceActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.vr.sdk.widgets.pano.VrPanoramaView
android:id="#+id/pano_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:layout_weight="5"
android:scrollbars="none" />
<TextView
android:id="#+id/titleTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/white"
android:text="VR Experience"
android:textAlignment="center"
android:textAppearance="#android:style/TextAppearance.Large"
android:textColor="#0000F0"
android:visibility="visible" />
<Button
android:id="#+id/buttonCitta"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Città" />
<fragment
class="com.google.android.gms.maps.SupportStreetViewPanoramaFragment"
android:id="#+id/streetviewpanorama"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
EDIT: #LucioB
a) those are the places I've tried to call loadPanoImage, but neither of them showed anything. It acts as nothing happens calling that method, the program keeps going to the other tasks. I'd like for images to be shown directly in VR when a button is clicked, or if that isn't possible to add the classic cardboard button in Street View mode to pass to VR view.
b) I mean the code isn't doing what I expected it to do. I thought that once I created VrPanoramaView in the layout and used it to show an image through .loadImageFromBitmap it would have shown the image I loaded from asset (I have an image saved on the virtual SD), and that once I was able to do that for a single image I would have found a way to do it for a whole path.
The code doesn't give any exception, I think I'm making a logic mistake or I didn't understand how VR api work.
EDIT: I've found that the java code is working, the problem was in the layout which didn't permit to see VrPanoramaView because it was obscured by StreetViewPanorama

Click effect/animation for all application

It is possible to create a click effect/animation for all clicks on my application?
Since I want this behaviour for all clicks events on my application, how should I do this? Is this bad for performance or resources of the smartphone?
It is hard to know without understanding the stack that has been built, that being said I think there are some safer and less methodologies to an onclick event that is the same across the board. For one I would not change fundamental nature of the "onClick" function, the lower level you mess with the more dangerous it is. That being said I think I would create my own version/function of onclick, maybe boomClick, where boomClick creates the animation that you want. Referencing a single function will barely decrease performance at all.
So, after a day working at this I managed to accomplish the expected behaviour.
Basically, I create my own Activity class which will do the animation work with the help of a custom lib. I'll try to explain what I did for future reference:
1. Add this lib to your project:
compile 'pl.droidsonroids.gif:android-gif-drawable:1.2.3'
2. Add these dimens to your "dimens.xml" file:
<dimen name="click_animation">100dp</dimen>
<dimen name="click_compensation">50dp</dimen>
3. Make the top parent of your activities layout a "RelativeLayout" and set a custom id:
<?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"
android:id="#+id/main_layout">
... the rest of the layout ...
</RelativeLayout>
4. Create your own "Activity" class:
public class MyActivity extends AppCompatActivity {
private RelativeLayout.LayoutParams params;
public void setClickAnimation(final Activity activity) {
// if you want to change the size of the animation, change the size on the dimens.xml
int size = (int) activity.getResources().getDimension(R.dimen.click_animation);
params = new RelativeLayout.LayoutParams(size, size);
// you want the parent layout of the activity
final RelativeLayout view = (RelativeLayout) activity.findViewById(R.id.main_layout);
view.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// you maybe won't need this compensation value
int compensation = (int) activity.getResources().getDimension(R.dimen.click_compensation);
try { startAnimation(view, (int) event.getX() - compensation, (int) event.getY() - compensation); }
catch (IOException e) { e.printStackTrace(); }
}
return true;
}
});
}
private void startAnimation(RelativeLayout view, int x, int y) throws IOException {
params.leftMargin = x;
params.topMargin = y;
// those are from the lib you imported
final GifImageView anim = new GifImageView(this);
// if you don't have it yet, put the gif you want on the assets folder
final GifDrawable gifFromResource = new GifDrawable(getAssets(), "click_animation.gif");
gifFromResource.addAnimationListener(new AnimationListener() {
#Override
public void onAnimationCompleted(int loopNumber) {
anim.setVisibility(View.GONE);
gifFromResource.stop();
gifFromResource.recycle();
}
});
anim.setBackground(gifFromResource);
gifFromResource.start();
view.addView(anim, params);
}
}
5. Make your Activities extend your "Activity" class:
public class FirstScreen extends MyActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cards_screen);
// call the method you created and pass the activity context
setClickAnimation(this);
}
}
As for resources spent: this looks like a good solution and I am getting a good performance. The application seems to not be wasting a lot of resources with this solution.

Android Camera preview not showing

I found a tutorial online here both for capturing images, they are very similar and I used one another to figure out why my Camera code isn't working.
I do not get any syntax errors in Android but when I go on the desired fragment it is just a white screen, there is no camera display and I have no idea why I have looked at both code examples in depth and googled my problem but cant find anything. The only difference with my code is that its a fragment instead of an activity. Can someone please help me?
Here is my code:
public class Image extends Fragment implements SurfaceHolder.Callback {
private ImageView imageView;
private SurfaceView mSurfaceView;
private Bitmap capturedImage;
//Camera
private SurfaceHolder sHolder;
private Camera mCamera;
private Parameters parameters;
/**********************************************/
public Image() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.image_activity, container, false);
imageView = (ImageView) view.findViewById(R.id.imageView);
mSurfaceView = (SurfaceView) view.findViewById(R.id.surfaceView);
//Get a surface
sHolder = mSurfaceView.getHolder();
//add the callback interface methods defined below as the Surface View callbacks
sHolder.addCallback(this);
//tells Android that this surface will have its data constantly replaced
sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
return view;
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, acquire the camera and tell it where
// to draw the preview.
mCamera = Camera.open();
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
mCamera.release();
mCamera = null;
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
//get camera parameters
parameters = mCamera.getParameters();
parameters.setPreviewSize(352, 288);
//set camera parameters
mCamera.setParameters(parameters);
mCamera.startPreview();
//sets what code should be executed after the picture is taken
Camera.PictureCallback mCall = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
//decode the data obtained by the camera into a Bitmap
capturedImage = BitmapFactory.decodeByteArray(data, 0, data.length);
String filename= Environment.getExternalStorageDirectory()
+ File.separator + "testimage.jpg";
FileOutputStream out = null;
try {
out = new FileOutputStream(filename);
capturedImage.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
// PNG is a lossless format, the compression factor (100) is ignored
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
//set the iv_image
imageView.setImageBitmap(capturedImage);
}
};
mCamera.takePicture(null, null, mCall);
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
Here is my XML file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<SurfaceView
android:id="#+id/surfaceView"
android:layout_height="0dip"
android:layout_width="0dip">
</SurfaceView>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageView">
</ImageView>
</LinearLayout>
Update 1:
Here is my manifest file, I forgot to include this:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
I have also enabled the permissions in marshmallow settings for the application but still doesn't show anything
Update 2:
Just tried it with a API 17 device and there is still no preview
Assuming all your code is actually running as you expect, one possibility: setPreviewSize(352, 288) - that size may not be supported.
You'll need to check the list of supported preview sizes and pick one, or use 320,240 or 640,480 which are basically always available.
Please make sure you have added the necessary camera permission into AndroidManifest.xml file & if you are using marshmallow please check one more step that permission are enabled from setting=> Applications=> Application Manager=> Your App=> Permissions
in XML android_height and android_width are 0, change it!

Glide overlays screen with loaded image parts

Since i could not find anything related in the internet, this is gonna be my first SO question:
Problem Description
I am experiencing the following issue:
In my app i have a RecyclerView with a GridLayoutManager which is displaying images loaded by Glide.
When scrolling slowly everything will work alright.
After scrolling fast up and down (to an extend one could arguably call it "abuse of scrolling") some image parts or whole images will randomly overlay my screen, so that the content below is no longer visible. This is especially the case on the edges of the screen.
The testing device where the described error occurs is a OnePlus One running CM12.1.1 (Android 5.1.1). I didn't test on other devices.
Any hints / help / explanation on why this is happening or how to fix it are appreciated.
CODE
Below is the code for the Adapter with an inner ViewHolder class:
public class PhotoListAdapter extends RecyclerView.Adapter<PhotoListAdapter.PhotoHolder>{
private ArrayList<PhotoDetail> mPhotos;
private String mAccessToken;
private int mUserId;
private int mPageCounter = 1;
private boolean mIsLoading = false;
private boolean mEndReached = false;
public PhotoListAdapter (String accessToken, int userId){
mPhotos = new ArrayList<>();
mAccessToken = accessToken;
mUserId = userId;
fetchPhotos();
}
#Override
public PhotoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_photo_list_item, parent, false);
PhotoHolder photoHolder = new PhotoHolder(itemView);
return photoHolder;
}
#Override
public void onBindViewHolder(PhotoHolder holder, int position) {
holder.bind(mPhotos.get(position));
if (position == mPhotos.size() - 6) fetchPhotos();
}
#Override
public int getItemCount() {
return mPhotos.size();
}
public void fetchPhotos () {
if (mIsLoading || mEndReached) return;
else {
mIsLoading = true;
//Retrofit call which will return a JSON Object with the Photo Details, like the filename
// With this information i can build the URL of the image
ApiProvider.getInstance().getApi().getPhotos(mUserId, mAccessToken, "time", "all", mPageCounter, mUserId, 32).enqueue(new Callback<PhotoResponseWrapper>() {
#Override
public void onResponse(Call<PhotoResponseWrapper> call, Response<PhotoResponseWrapper> response) {
if (response.code() == HttpURLConnection.HTTP_OK){
int photoCount = response.body().getPhotoResponse().getPhotosCount();
if (photoCount != 32) mEndReached = true;
Collections.addAll(mPhotos, response.body().getPhotoResponse().getPhotos());
notifyItemRangeInserted(mPhotos.size() - photoCount,photoCount);
mPageCounter++;
}
mIsLoading = false;
}
#Override
public void onFailure(Call<PhotoResponseWrapper> call, Throwable t) {
mIsLoading = false;
}
});
}
}
class PhotoHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private ImageView mPhotoView;
private PhotoDetail mPhotoDetail;
public PhotoHolder(View itemView) {
super(itemView);
mPhotoView = (ImageView) itemView.findViewById(R.id.img_photo);
mPhotoView.setOnClickListener(this);
}
public void bind (PhotoDetail photoDetail){
mPhotoDetail = photoDetail;
String photoUrl = Api.Endpoints.PHOTOS_SMALL + photoDetail.getUserId() + '/' + photoDetail.getFileName();
mPhotoView.setContentDescription(photoDetail.getDescription());
// First stop all pending image loads
Glide.clear(mPhotoView);
// Then load new url
Glide.with(mPhotoView.getContext())
.load(photoUrl)
.into(mPhotoView);
}
#Override
public void onClick(View v) {
}
}
}
Below is the XML of a single Item:
<?xml version="1.0" encoding="utf-8"?>
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/img_photo"
android:clickable="true"
android:layout_width="match_parent"
android:layout_height="#dimen/height_photo_item"
android:padding="#dimen/padding_photo_item"
android:scaleType="centerCrop"/>
Below is the XML of the RecyclerView:
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/layout_swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingRight="#dimen/padding_photo_item"
android:paddingLeft="#dimen/padding_photo_item"
android:paddingTop="#dimen/padding_photo_item"
tools:context=".fragments.PhotoListFragment">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
EXAMPLES
Some visual examples of the bug are these screenshots:
You have to use placeholder image.
Glide.with(mPhotoView.getContext())
.load(photoUrl)
.placeholder(R.drawable.image_placeholder) // Your placeholder image
.into(mPhotoView);
I had the same problem and setting the placeholder eliminated it for me.
Since I couldn't find any information on how to fix this, i tried out the major alternative image loading & caching library - Picasso.
With this library the bug mentioned above wasn't reproducible for me, so i guess it is really Glide specific.

Can I scroll a ScrollView programmatically in Android?

Is there any way to scroll a ScrollView programmatically to a certain position?
I have created dynamic TableLayout which is placed in a ScrollView. So I want that on a specific action (like clicking a Button, etc.) the particular row should scroll automatically to a top position.
Is it possible?
The answer from Pragna does not work always, try this:
mScrollView.post(new Runnable() {
public void run() {
mScrollView.scrollTo(0, mScrollView.getBottom());
}
});
or
mScrollView.post(new Runnable() {
public void run() {
mScrollView.fullScroll(mScrollView.FOCUS_DOWN);
}
});
if You want to scroll to start
mScrollView.post(new Runnable() {
public void run() {
mScrollView.fullScroll(mScrollView.FOCUS_UP);
}
});
ScrollView sv = (ScrollView)findViewById(R.id.scrl);
sv.scrollTo(0, sv.getBottom());
or
sv.scrollTo(5, 10);
I wanted the scrollView to scroll directly after onCreateView() (not after e.g. a button click). To get it to work I needed to use a ViewTreeObserver:
mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
mScrollView.post(new Runnable() {
public void run() {
mScrollView.fullScroll(View.FOCUS_DOWN);
}
});
}
});
But beware that this will be called everytime something gets layouted (e.g if you set a view invisible or similar) so don't forget to remove this listener if you don't need it anymore with:
public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim) on SDK Lvl < 16
or
public void removeOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim) in SDK Lvl >= 16
There are a lot of good answers here, but I only want to add one thing. It sometimes happens that you want to scroll your ScrollView to a specific view of the layout, instead of a full scroll to the top or the bottom.
A simple example: in a registration form, if the user tap the "Signup" button when a edit text of the form is not filled, you want to scroll to that specific edit text to tell the user that he must fill that field.
In that case, you can do something like that:
scrollView.post(new Runnable() {
public void run() {
scrollView.scrollTo(0, editText.getBottom());
}
});
or, if you want a smooth scroll instead of an instant scroll:
scrollView.post(new Runnable() {
public void run() {
scrollView.smoothScrollTo(0, editText.getBottom());
}
});
Obviously you can use any type of view instead of Edit Text. Note that getBottom() returns the coordinates of the view based on its parent layout, so all the views used inside the ScrollView should have only a parent (for example a Linear Layout).
If you have multiple parents inside the child of the ScrollView, the only solution i've found is to call requestChildFocus on the parent view:
editText.getParent().requestChildFocus(editText, editText);
but in this case you cannot have a smooth scroll.
I hope this answer can help someone with the same problem.
Use something like this:
mScrollView.scrollBy(10, 10);
or
mScrollView.scrollTo(10, 10);
Try using scrollTo method More Info
If you want to scroll instantly then you can use :
ScrollView scroll= (ScrollView)findViewById(R.id.scroll);
scroll.scrollTo(0, scroll.getBottom());
OR
scroll.fullScroll(View.FOCUS_DOWN);
OR
scroll.post(new Runnable() {
#Override
public void run() {
scroll.fullScroll(View.FOCUS_DOWN);
}
});
Or if you want to scroll smoothly and slowly so you can use this:
private void sendScroll(){
final Handler handler = new Handler();
new Thread(new Runnable() {
#Override
public void run() {
try {Thread.sleep(100);} catch (InterruptedException e) {}
handler.post(new Runnable() {
#Override
public void run() {
scrollView.fullScroll(View.FOCUS_DOWN);
}
});
}
}).start();
}
**to scroll up to desired height. I have come up with some good solution **
scrollView.postDelayed(new Runnable() {
#Override
public void run() {
scrollView.scrollBy(0, childView.getHeight());
}
}, 100);
Yes, you can.
Let's say you got one Layout and inside that, you got many Views. So if you want to scroll to any View programmatically, you have to write the following code snippet:
For example:
content_main.xml
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="#+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/txtView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
MainActivity.java
ScrollView scrollView = (ScrollView) findViewById(R.id.scrollView);
Button btn = (Button) findViewById(R.id.ivEventBanner);
TextView txtView = (TextView) findViewById(R.id.ivEditBannerImage);
If you want to scroll to a specific View, let's say txtview, in this case, just write:
scrollView.smoothScrollTo(txtView.getScrollX(),txtView.getScrollY());
And you are done.
I got this to work to scroll to the bottom of a ScrollView (with a TextView inside):
(I put this on a method that updates the TextView)
final ScrollView myScrollView = (ScrollView) findViewById(R.id.myScroller);
myScrollView.post(new Runnable() {
public void run() {
myScrollView.fullScroll(View.FOCUS_DOWN);
}
});
Note: if you already in a thread, you have to make a new post thread, or it's not scroll new long height till the full end (for me).
For ex:
void LogMe(final String s){
runOnUiThread(new Runnable() {
public void run() {
connectionLog.setText(connectionLog.getText() + "\n" + s);
final ScrollView sv = (ScrollView)connectLayout.findViewById(R.id.scrollView);
sv.post(new Runnable() {
public void run() {
sv.fullScroll(sv.FOCUS_DOWN);
/*
sv.scrollTo(0,sv.getBottom());
sv.scrollBy(0,sv.getHeight());*/
}
});
}
});
}
Adding another answer that does not involve coordinates.
This will bring your desired view to focus (but not to the top position) :
yourView.getParent().requestChildFocus(yourView,yourView);
public void RequestChildFocus (View child, View focused)
child - The child of this ViewParent that wants focus. This view will contain the focused view. It is not necessarily the view that actually has focus.
focused - The view that is a descendant of child that actually has focus
Everyone is posting such complicated answers.
I found an easy answer, for scrolling to the bottom, nicely:
final ScrollView myScroller = (ScrollView) findViewById(R.id.myScrollerView);
// Scroll views can only have 1 child, so get the first child's bottom,
// which should be the full size of the whole content inside the ScrollView
myScroller.smoothScrollTo( 0, myScroller.getChildAt( 0 ).getBottom() );
And, if necessary, you can put the second line of code, above, into a runnable:
myScroller.post( new Runnable() {
#Override
public void run() {
myScroller.smoothScrollTo( 0, myScroller.getChildAt( 0 ).getBottom() );
}
}
It took me much research and playing around to find this simple solution. I hope it helps you, too! :)
just page scroll:
ScrollView sv = (ScrollView) findViewById(your_scroll_view);
sv.pageScroll(View.FOCUS_DOWN);
I was using the Runnable with sv.fullScroll(View.FOCUS_DOWN);
It works perfectly for the immediate problem, but that method makes ScrollView take the Focus from the entire screen, if you make that AutoScroll to happen every time, no EditText will be able to receive information from the user, my solution was use a different code under the runnable:
sv.scrollTo(0, sv.getBottom() + sv.getScrollY());
making the same without losing focus on important views
greetings.
it's working for me
mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
mScrollView.post(new Runnable() {
public void run() {
mScrollView.fullScroll(View.FOCUS_DOWN);
}
});
}
});
private int totalHeight = 0;
ViewTreeObserver ScrollTr = loutMain.getViewTreeObserver();
ScrollTr.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
loutMain.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
loutMain.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
TotalHeight = loutMain.getMeasuredHeight();
}
});
scrollMain.smoothScrollTo(0, totalHeight);
I had to create Interface
public interface ScrollViewListener {
void onScrollChanged(ScrollViewExt scrollView,
int x, int y, int oldx, int oldy);
}
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView;
public class CustomScrollView extends ScrollView {
private ScrollViewListener scrollViewListener = null;
public ScrollViewExt(Context context) {
super(context);
}
public CustomScrollView (Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CustomScrollView (Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setScrollViewListener(ScrollViewListener scrollViewListener) {
this.scrollViewListener = scrollViewListener;
}
#Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (scrollViewListener != null) {
scrollViewListener.onScrollChanged(this, l, t, oldl, oldt);
}
}
}
<"Your Package name ".CustomScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true"
android:scrollbars="vertical">
private CustomScrollView scrollView;
scrollView = (CustomScrollView)mView.findViewById(R.id.scrollView);
scrollView.setScrollViewListener(this);
#Override
public void onScrollChanged(ScrollViewExt scrollView, int x, int y, int oldx, int oldy) {
// We take the last son in the scrollview
View view = (View) scrollView.getChildAt(scrollView.getChildCount() - 1);
int diff = (view.getBottom() - (scrollView.getHeight() + scrollView.getScrollY()));
// if diff is zero, then the bottom has been reached
if (diff == 0) {
// do stuff
//TODO keshav gers
pausePlayer();
videoFullScreenPlayer.setVisibility(View.GONE);
}
}

Categories

Resources