How to Scroll Image Horizontally in Android and Get Input From User?

755 views Asked by At

enter image description here

I am working on Camera application, I am having image with numbers from 1 to 35 I want to achieve following structure for controlling zoom feature but I got stuck in user interface implementation.

Application requirement is, user can scroll the image from left to right OR right to left and select one number from image so I can use that number and set zoom.

How to scroll the image and get input from user ?

is there any library available for this ?

2

There are 2 answers

3
Antwan Kakki On BEST ANSWER

Crop the image to the size you want displayed and centered where you want, register to drag events on the image view, find out how much the user scrolled and adjust your crop center based on that value. Calculate how much the user has to scroll for your number to change and change an int value accordingly.

Check out https://developer.android.com/training/gestures/scale.html for more info on handling drag events.

I'll post code when I get home tonight if you still need it


** I can't add images since I have (re)started using stack overflow recentley, refer to the image in the link below for [A], [B]...** https://i.stack.imgur.com/9b7kg.png

Explanation:

Imagine you have an image like [A] and you want to implement custom scrolling. Theoretically, divide it into parts like in [B]. The way I would implement scrolling on an imageview is create a bitmap out of the image that covers only parts of it (for me, the image is size 5*180x 180, I want the bitmap displayed to be 3*180 x 180 so it can only cover 3 boxes at most (refer to [C]). Then I would add an OnTouchListener to the activity and listen to touches on the imageView, when the imageView is dragged on, register the difference and create a new image accordingly [D], make sure the new bitmap image doesn't go out of focus. Look at my implementation below for reference.

Implementation

My layout file

    <TextView android:text="@string/hello_world" android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentStart="true"
        android:textAlignment="center"
        android:id="@+id/textView" />

    <ImageView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:scaleType="fitXY"
        android:id="@+id/imageView"
        android:layout_alignParentStart="true"
        android:layout_alignEnd="@+id/textView"
        android:layout_alignParentBottom="true" />

</RelativeLayout>

My Activity

// register as View.OnTouchListener to recieve updates when an object 
// registered to emit the touch event gets touched 
public class MainActivity extends Activity implements View.OnTouchListener {

    static final int  SCROLLER_WIDTH = 180*3;
    static final int SCROLLER_HEIGHT = 180;

    ImageView imageView;  // the imageView to display the rendered image
    Bitmap scrollerImage; // the original, uncut, image
    TextView textView;    // textView to display current indicator
    int scrollerStartPos = 0; // where to start cropping from
    int scrollerValue = 1;  // what value is currently indicated
    float previousX = 0;  // previous X location, used to calculate difference in pixels scrolled over


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // get the image view we want
        imageView = (ImageView) findViewById(R.id.imageView);

        // set the touch listener on the image
        imageView.setOnTouchListener(this);

        // get the text 
        textView = (TextView) findViewById(R.id.textView);

        // grab the uncut original image
        scrollerImage = BitmapFactory.decodeResource(getResources(), R.drawable.img1);

        // render the image
        RenderImage();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    /**
     * this method will render the part of the image that should be 
     * displayed, it also calculates the scroller value
     */
    private void RenderImage()
    {
        // create the cropped version we want to show and render it
        Bitmap renderImg = Bitmap.createBitmap(scrollerImage, scrollerStartPos,0,SCROLLER_WIDTH, SCROLLER_HEIGHT);
        // set imageView to be the bitmap
        imageView.setImageBitmap(renderImg);

        // update scroller value
        if (scrollerStartPos < 180*2)
            scrollerValue = 1;
        else if (scrollerStartPos < 180*4)
            scrollerValue = 2;
        else
            scrollerValue = 3;

        // render scroller value on the text
        textView.setText("The scroller value is: " + scrollerValue);
    }

    /**
     * called when imageView is touched
     */
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // the user just touched the imageView, record the x location
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            previousX = (int) event.getRawX();
        }
        // the user is moving over (scrolling), act accordingly!
        else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            float x = event.getRawX();

            // move start position accordingly
            scrollerStartPos -= x - previousX;

            // make sure scroller is within range
            scrollerStartPos = Math.max(scrollerStartPos, 0);
            scrollerStartPos = Math.min(scrollerStartPos, scrollerImage.getWidth() - SCROLLER_WIDTH);

            // update the previous x value
            previousX = x;

            // update image
            RenderImage();
        }
        return true;
    }
}
0
AndroidEnthusiast On

Check out this library called Horizontal Picker -> https://github.com/blazsolar/HorizontalPicker

You can easily change the labels from "Item " to the index you want