Adding components to a layout via JAVA in android - android

Actually the main layout is a relative layout which interns contains a relative layout in it. The main objective is to add images to the inner relative layout .
I tried this out but didn't succeed . This is my code :
import android.os.Bundle;
import android.view.Display;
import android.view.Gravity;
import android.view.animation.Animation;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.app.Activity;
import android.graphics.Point;
public class MainActivity extends Activity {
Display display;
Point point;
int width;
int height;
Animation up, down, right, left;
RelativeLayout rl, rl2;
Integer[] pics = { R.drawable.img1, R.drawable.img2,R.drawable.img3, R.drawable.img4,
R.drawable.img5, R.drawable.img6,R.drawable.img7, R.drawable.img8,
R.drawable.img9, R.drawable.img10,R.drawable.img11, R.drawable.img12,
R.drawable.img13, R.drawable.img14,R.drawable.img15};
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Init();
}
private void Init() {
// TODO Auto-generated method stub
rl = (RelativeLayout) findViewById(R.id.Rlayout);
rl.setGravity(Gravity.CENTER);
int x = 0;
int y = 0;
for(int i = 1 ; i<16 ; i++ ){
ImageView img = new ImageView(this);
img.setImageResource(pics[i-1]);
int tempx = img.getWidth();
int tempy = img.getHeight();
rl.addView(img, x, y);
x += tempx;
if(i%4 == 0){
x = 0;
y += tempy;
}
}
rl.bringToFront();
}
}
The XML code for the layout being used is :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/R1Layout">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:gravity="center"
android:id="#+id/Rlayout" >
</RelativeLayout>
</RelativeLayout>
The output that i get is a blank screen .
Help me out with a solution how to display the images within the inner relative layout
Thanks in advance ,

To insert images into the inner RelativeLayout, you need to use ImageView object. You can do it using the addView() method that is available to RelativeLayout (through inheritance from ViewGroup class). You can do it as follows within your activity (you have to decide where you want to place this):
RelativeLayout rl = (RelativeLayout) findViewById(R.id.Rlayout); // find inner layout
ImageView iview = new Image(this);
// Set image view parameters - refer to Android documentation for this
rl.addView(iview); // and so on.
// You can add as many items as you want to any layout you want in this manner

I think you are misunderstanding, x and y are not the coordinates, are width and height respectively in
rl.addView(img, x, y);
and you can´t get the size of the imageviews with:
int tempx = img.getWidth();
int tempy = img.getHeight();
You must use a container to set size and coordinates to your imageview´s:
RelativeLayout.LayoutParams params;
params = new RelativeLayout.LayoutParams(100, 100);
params.leftMargin = x;
params.topMargin = y;
rl.addView(img,params);
this is an example of how to do it:
private void Init() {
// TODO Auto-generated method stub
int x = 0;
int y = 0;
rl = (RelativeLayout) findViewById(R.id.Rlayout);
rl.setGravity(Gravity.CENTER);
for(int i = 0 ; i<14 ; i++ ){
ImageView img = new ImageView(this);
img.setImageResource(pics[i]);
//int tempx = img.getWidth();
//int tempy = img.getHeight();
int tempx = 100;
int tempy = 100;
//rl.addView(img, x, y);
x += tempx;
if(i%4 == 0){
x = 0;
y += tempy;
}
RelativeLayout.LayoutParams params;
params = new RelativeLayout.LayoutParams(100, 100);
params.leftMargin = x;
params.topMargin = y;
rl.addView(img,params);
}
rl.bringToFront();
}
like Rajesh, i recommend too the use of a Gridview instead of RelativeLayout.
See this example:
GridView and excess space padding

Related

Android addView and removeView in the same method

I'm calling this method that should redraw a pointer in the position given in every call.
ImageView ivPointer=null;
public void moveCursor(Bitmap bmPuntero, int x, int y)
{
RelativeLayout rl = (RelativeLayout) findViewById(R.id.gamelayout);
if (ivPointer!=null)
rl.removeView(ivPointer);
ivPointer = new ImageView(this);
ivPointer.setImageBitmap(bmPuntero);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(65, 65);
params.leftMargin = x;
params.topMargin = y;
rl.addView(ivPointer, params);
}
The result is that the bitmap isn't showed. If I remove the lines that remove the view, I see how the bitmap is drawn multiple times, so the add part should be correct.
Try this:
{
// Somewhere (in onCreate of the Activity for example):
RelativeLayout rl = (RelativeLayout) findViewById(R.id.gamelayout);
ImageView ivPointer = initPointer(this, bmPuntero); // Get image from somewhere
rl.addView(ivPointer);
}
// To update the cursor's po
public static void moveCursor(ImageView pointer, int x, int y) {
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) pointer.getLayoutParams();
params.leftMargin = x;
params.topMargin = y;
pointer.setLayoutParams(params);
pointer.requestLayout(); // Refresh the layout
}
// Call this method to initialise the pointer (in onCreate of your Activity
// for example)
public static ImageView initPointer(Context context, Bitmap bmp) {
// Define the LayoutParams
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(65, 65);
params.leftMargin = DEFAULT_POS_X; // TODO: Constants to be defined
params.topMargin = DEFAULT_POS_Y;
// Init the ImageView
ImageView pointer = new ImageView(context);
pointer.setImageBitmap(bmp);
pointer.setLayoutParams(params);
return pointer;
}

create vertical lines in seekbar

I'm trying to create something like this. The problem is how to create vertical lines close to the seekbar. I tried the code given here, but the seekbar line disappears. Any help would be appreciated. Here is what I've done so far.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SeekBar sb = (SeekBar)findViewById(R.id.seekBar1);
//Get the width of the main view.
Display display = getWindowManager().getDefaultDisplay();
Point displaysize = new Point();
display.getSize(displaysize);
int width = displaysize.x;
//set the seekbar maximum (Must be a even number, having a remainder will cause undersirable results)
//this variable will also determine the number of points on the scale.
int seekbarmax = 10;
int seekbarpoints = (width/seekbarmax); //this will determine how many points on the scale there should be on the seekbar
//find the seekbar in the view, and set some behaviour properties
SeekBar seekbar = (SeekBar)findViewById(R.id.seekBar1);
//Set the seekbar to a max range of 10
seekbar.setMax(seekbarmax);
//Create a new bitmap that is the width of the screen
Bitmap bitmap = Bitmap.createBitmap(width, 100, Bitmap.Config.ARGB_8888);
//A new canvas to draw on.
Canvas canvas = new Canvas(bitmap);
//a new style of painting - colour and stoke thickness.
Paint paint = new Paint();
paint.setColor(Color.BLUE); //Set the colour to red
paint.setStyle(Paint.Style.STROKE); //set the style
paint.setStrokeWidth(1); //Stoke width
Paint textpaint = new Paint(Paint.ANTI_ALIAS_FLAG);
textpaint.setColor(Color.rgb(61, 61, 61));// text color RGB
textpaint.setTextSize(28);// text size
int point = 0; //initiate the point variable
//Start a for loop that will loop seekbarpoints number of times.
for (int i = 0; i < seekbarpoints; i++ ){
if ((i%2)==0) {
//short line
point = point + seekbarpoints;
canvas.drawLine(point, 30, point, 0, paint);
//drawLine(startx,startx,endy,endy)
}
//Create a new Drawable
Drawable d = new BitmapDrawable(getResources(),bitmap);
//Set the seekbar widgets background to the above drawable.
seekbar.setProgressDrawable(d);
}
}
}
I was searching for the this for long time and only got an answer to draw the numbers. Thus I decided to do it myself. I took the solution having only the steps and extended it by adding the logic for the intervals.
Please see the below image.
I then successfully created a seekbar with interval lables and vertical lines over seekbar. The above image is what I've achieved.
However there are few optimization in the padding which you can work on adjusting the dimensions.
Solution :
The xml file for the intervals:
seekbar_with_intervals_labels
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/textViewInterval"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="#707070"/>
XML for the Vertical deviders : seekbar_vertical_lines
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/textViewVerticalLine"
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#drawable/lines" />
Then the custom Seekbar class :
package com.example.abc.myapplication;
import java.util.List;
import java.util.concurrent.locks.ReadWriteLock;
import com.example.abc.myapplication.R;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
public class SeekbarWithIntervals extends LinearLayout {
private RelativeLayout RelativeLayout = null;
private SeekBar Seekbar = null;
private RelativeLayout Divider = null;
private View verticalLine = null;
private int WidthMeasureSpec = 0;
private int HeightMeasureSpec = 0;
public SeekbarWithIntervals(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
getActivity().getLayoutInflater()
.inflate(R.layout.seekbar_with_intervals, this);
}
private Activity getActivity() {
return (Activity) getContext();
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
verticalLine = new View(getActivity());
verticalLine.setLayoutParams(new LayoutParams(2, LayoutParams.MATCH_PARENT));
verticalLine.setBackgroundColor(Color.BLACK);
if (changed) {
alignIntervals();
// We've changed the intervals layout, we need to refresh.
RelativeLayout.measure(WidthMeasureSpec, HeightMeasureSpec);
RelativeLayout.layout(RelativeLayout.getLeft(), RelativeLayout.getTop(), RelativeLayout.getRight(), RelativeLayout.getBottom());
}
}
private void alignIntervals() {
int widthOfSeekbarThumb = getSeekbarThumbWidth();
int thumbOffset = widthOfSeekbarThumb / 2;
int widthOfSeekbar = getSeekbar().getWidth();
int firstIntervalWidth = getRelativeLayout().getChildAt(0).getWidth();
int remainingPaddableWidth = widthOfSeekbar - firstIntervalWidth - widthOfSeekbarThumb;
int numberOfIntervals = getSeekbar().getMax();
int maximumWidthOfEachInterval = remainingPaddableWidth / numberOfIntervals;
alignFirstInterval(thumbOffset);
alignIntervalsInBetween(maximumWidthOfEachInterval);
alignLastInterval(thumbOffset, maximumWidthOfEachInterval);
}
private int getSeekbarThumbWidth() {
return getResources().getDimensionPixelOffset(R.dimen.seekbar_thumb_width);
}
private void alignFirstInterval(int offset) {
TextView firstInterval = (TextView) getRelativeLayout().getChildAt(0);
firstInterval.setPadding(offset - 10, 0, 0, 0);
TextView firstLine = (TextView) getDivider().getChildAt(0);
firstLine.setPadding(offset + 10, 0, 0, 0);
}
private void alignIntervalsInBetween(int maximumWidthOfEachInterval) {
int widthOfPreviousIntervalsText = 0;
int widthOfPreviousLine = 0;
// Don't align the first or last interval.
for (int index = 1; index < (getRelativeLayout().getChildCount() - 1); index++) {
TextView textViewInterval = (TextView) getRelativeLayout().getChildAt(index);
int widthOfText = textViewInterval.getWidth();
// This works out how much left padding is needed to center the current interval.
//int leftPadding = Math.round(maximumWidthOfEachInterval - (widthOfText / 2) - (widthOfPreviousIntervalsText / 2) - (widthOfText / 2));
int leftPadding = Math.round(maximumWidthOfEachInterval - (widthOfText / 2) - (widthOfPreviousIntervalsText / 2) - (widthOfText / index ) + index + 5 * 5);
textViewInterval.setPadding(leftPadding, 0, 0, 0);
widthOfPreviousIntervalsText = widthOfText;
TextView textViewLine = (TextView) getDivider().getChildAt(index);
int widthOfLine = textViewLine.getWidth();
// This works out how much left padding is needed to center the current interval.
leftPadding = (maximumWidthOfEachInterval + (index + (maximumWidthOfEachInterval / 10)) - (index * 4)); //Math.round(maximumWidthOfEachInterval + (widthOfLine ) + (widthOfPreviousLine ));
//leftPadding = Math.round((maximumWidthOfEachInterval - (widthOfPreviousLine / index) - (widthOfPreviousLine / index) - (widthOfPreviousLine / index)) + 10);
textViewLine.setPadding(leftPadding , 0, 0, 0);
widthOfPreviousLine = widthOfLine;
}
}
private void alignLastInterval(int offset, int maximumWidthOfEachInterval) {
int lastIndex = getRelativeLayout().getChildCount() - 1;
TextView lastInterval = (TextView) getRelativeLayout().getChildAt(lastIndex);
int widthOfText = lastInterval.getWidth();
int leftPadding = Math.round(maximumWidthOfEachInterval - widthOfText - offset);
lastInterval.setPadding(leftPadding + 20, 0, 0, 0);
TextView lastLine = (TextView) getDivider().getChildAt(lastIndex);
leftPadding = Math.round(maximumWidthOfEachInterval - (widthOfText / 5) - (widthOfText / 5) - (widthOfText / 5 ) + 3 * 10);
lastLine.setPadding(leftPadding , 0, 0, 0);
}
protected synchronized void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
WidthMeasureSpec = widthMeasureSpec;
HeightMeasureSpec = heightMeasureSpec;
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public int getProgress() {
return getSeekbar().getProgress();
}
public void setProgress(int progress) {
getSeekbar().setProgress(progress);
}
public void setIntervals(List<String> intervals) {
displayIntervals(intervals);
getSeekbar().setMax(intervals.size() - 1);
}
private void displayIntervals(List<String> intervals) {
int idOfPreviousInterval = 0;
int idOfPreviousLine = 0;
if (getRelativeLayout().getChildCount() == 0) {
for (String interval : intervals) {
TextView textViewInterval = createInterval(interval);
alignTextViewToRightOfPreviousInterval(textViewInterval, idOfPreviousInterval);
TextView textViewVerticaLine = createVerticalLine();
alignTextViewToRightOfPreviousInterval(textViewVerticaLine, idOfPreviousLine);
idOfPreviousLine = textViewVerticaLine.getId();
idOfPreviousInterval = textViewInterval.getId();
getRelativeLayout().addView(textViewInterval);
getDivider().addView(textViewVerticaLine);
}
}
}
private TextView createInterval(String interval) {
View textBoxView = (View) LayoutInflater.from(getContext())
.inflate(R.layout.seekbar_with_intervals_labels, null);
TextView textView = (TextView) textBoxView
.findViewById(R.id.textViewInterval);
textView.setId(View.generateViewId());
textView.setText(interval);
return textView;
}
private TextView createVerticalLine() {
View textBoxView = (View) LayoutInflater.from(getContext())
.inflate(R.layout.seekbar_vertical_lines, null);
TextView textView = (TextView) textBoxView
.findViewById(R.id.textViewVerticalLine);
textView.setId(View.generateViewId());
return textView;
}
private void alignTextViewToRightOfPreviousInterval(TextView textView, int idOfPreviousInterval) {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
if (idOfPreviousInterval > 0) {
params.addRule(RelativeLayout.RIGHT_OF, idOfPreviousInterval);
}
textView.setLayoutParams(params);
}
public void setOnSeekBarChangeListener(OnSeekBarChangeListener onSeekBarChangeListener) {
getSeekbar().setOnSeekBarChangeListener(onSeekBarChangeListener);
}
private RelativeLayout getRelativeLayout() {
if (RelativeLayout == null) {
RelativeLayout = (RelativeLayout) findViewById(R.id.intervals);
}
return RelativeLayout;
}
private SeekBar getSeekbar() {
if (Seekbar == null) {
Seekbar = (SeekBar) findViewById(R.id.seekbar);
}
return Seekbar;
}
private RelativeLayout getDivider() {
if (Divider == null) {
Divider = (RelativeLayout) findViewById(R.id.fl_divider);
}
return Divider;
}
}
Then the MainActivity where we dynamically add the intervals.
public class MainActivity extends AppCompatActivity {
private SeekbarWithIntervals SeekbarWithIntervals = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List<String> seekbarIntervals = getIntervals();
getSeekbarWithIntervals().setIntervals(seekbarIntervals);
}
private List<String> getIntervals() {
return new ArrayList<String>() {{
add("45");
add("55");
add("65");
add("75");
add("85");
add("95");
}};
}
private SeekbarWithIntervals getSeekbarWithIntervals() {
if (SeekbarWithIntervals == null) {
SeekbarWithIntervals = (SeekbarWithIntervals) findViewById(R.id.seekbarWithIntervals);
}
return SeekbarWithIntervals;
}
}
You can put the padding bottom of the divider so as to push it upwards like in your image.
Note : You can also have a single layout defining the divider and the number layout.
You will need two PNG drawables one for background and one for progress.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#android:id/background"
android:drawable="#drawable/seekbar_drawable_frost" />
<item
android:id="#android:id/progress"
android:drawable="#drawable/seekbar_drawable_frost_progress" />
</layer-list>

Android GridLayout only shows last child

I am new to Android Development. I have been working with using a GridLayout to display Dynamically inserted ImageViews.
My issue is located in "onFocusWindowChanged" but I pasted my onCreate where I do my assignments of the images.
private List<Behavior> behaviors = null;
private static int NUM_OF_COLUMNS = 2;
private List<ImageView> images;
private GridLayout grid;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_behaviors);
XMLPullParserHandler parser = new XMLPullParserHandler();
try {
behaviors = parser.parse(getAssets().open("catagories.xml"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
grid = (GridLayout) findViewById(R.id.behaviorGrid);
images = new ArrayList<ImageView>();
grid.setColumnCount(NUM_OF_COLUMNS);
grid.setRowCount(behaviors.size() / NUM_OF_COLUMNS);
for (Behavior behavior : behaviors)
images.add(this.getImageViewFromName(behavior.getName()));
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
View view = (View) findViewById(R.id.scrollView);
int width = (int) (view.getWidth() * .45);
Log.i("ViewWidth", Integer.toString(width));
GridLayout.LayoutParams lp = new GridLayout.LayoutParams();
lp.height = width;
lp.width = width;
int childCount = images.size();
ImageView image;
for (int i = 0; i < childCount-1; i++) {
image = images.get(i);
image.setLayoutParams(lp);
grid.addView(image);
}
}
In my (short) previous experience, using
grid.add(View);
worked fine, but now I am only seeing the last child display only. Looking through the debugger I can see that the gridview is being populated with more than just the last element, as well as the last imageview.
Thank you for your help
you should create a GridLayout.LayoutParams for each ImageView:
for (int i = 0; i < childCount-1; i++) {
GridLayout.LayoutParams lp = new GridLayout.LayoutParams();
lp.height = width;
lp.width = width;
......
}
GridLayout.LayoutParams contains location information, e.g [column:2, row:3]. In your code, all ImageViews are set the same GridLayout.LayoutParams, so they are located in the same cell(overlapping each other).
When use LinearLayout.LayoutParams instead, there is no location information in it. GridLayout will create a new GridLayout.LayoutParams for each child view, so all ImageViews use their own different GridLayout.LayoutParams and location.
Wish this help. You can read the GridLayout.java and ViewGroup.java for more details.
So I solved my issue, although I'm not sure how-
GridLayout.LayoutParams lp = new GridLayout.LayoutParams();
changed to...
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(x,y);
made it work just as I wanted it. But I'm not sure why- If anyone could explain, please do :)

how to get the particular sub view id from the view in android?

I created a dynamic view that contains FrameLayout, and it contains ImageViews. Now, when I touch the particular image on frame layout, I want know the ID of the ImageView.
So, here are my questions:
How can I set the ID for the ImageView?
How can I recognize particular ImageView is touched?
Here is the sample snippet of the code:
for (int j = 0; j < _pageslist.size(); j++) {
FrameLayout frame = new FrameLayout(HLActivity.this);
LayoutParams params = new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
frame.setLayoutParams(params);
ImageView mainimage = new ImageView(HLActivity.this);
mainimage.setImageBitmap(ReusableMethods.getBitmapFromURL(_pageslist.get(j)
.getThumbnail().toString()));
mainimage.setScaleType(ScaleType.FIT_XY);
mainimage.setLayoutParams(params);
frame.addView(mainimage, params);
if (_pageslist.get(j).isHasspots()) {
System.out.println(_pageslist.get(j).isHasspots());
System.out.println(_pageslist.get(j).getSPOTS());
ArrayList<Hotspot> hotspots_array = _pageslist.get(j).getSPOTS();
for (int i = 0; i < hotspots_array.size(); i++) {
Hotspot hotspot = hotspots_array.get(i);
System.out.println("hotspot :: " + hotspot.getType());
ImageView spotimage = new ImageView(HLActivity.this);
spotimage.setBackgroundColor(Color.parseColor("#88676767"));
float startx, starty, endx, endy;
startx = (float) (Float.parseFloat(hotspot.getX()) * ivw) / 100;
starty = (float) (Float.parseFloat(hotspot.getY()) * ivh) / 100;
endx = (float) ((Float.parseFloat(hotspot.getX()) +
Float.parseFloat(hotspot.getWidth())) * ivw) / 100;
endy = (float) ((Float.parseFloat(hotspot.getY()) +
Float.parseFloat(hotspot.getHeight())) * ivh) / 100;
params = new FrameLayout.LayoutParams(
(int) ((Float.parseFloat(hotspot.getWidth()) * ivw)/100),
(int) ((Float.parseFloat(hotspot.getHeight()) * ivh)/100));
params.leftMargin = (int) startx;
params.topMargin = (int) starty;
frame.addView(spotimage, params);
}
}
_view.add(frame);
}
adapter = new ViewPagerAdapter(HLActivity.this, _view,
_pageslist, ivw, ivh, getStatusBarHeight());
viewPager.setAdapter(adapter);
you have to set ontouch listener to your image:
yourImage.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent arg1) {
// this is your id you can pass it
v.getId()
// TODO Auto-generated method stub
return false;
}
});
If you only want to identify the view which is touched, you can add listeners to your dynamic image views also. Like below
spotimage.setOnClickListener(new OnClickListener() {`
#Override
public void onClick(View v) {
}
});
and in the onClick methord you can write code specific to each image view, or if you strictly want to set the id for image views, you can use spotimage.setId(1)
Id can be any integer value, but you have to make sure no conflict will occur with other id values. and in any listener like OnClickListenet, you can check the image view id byint temp = view.getId();

Gallery like view with center image zoom

Here I need a gallery like view with only three images to be shown at a time on screen. In this the middle image will be larger than the two other images on its sides.
If the user scrolls the view next images will slide on screen as it does in gallery and at a time only three images will be shown out of which the center image should automatically zoom when it is shown on screen and remaining two should be smaller than it.
Here I can't use gallery because it is depreciated in android.
I was able to make a gallery like view with help of viewpager using code on this link. It shows only three images on screen at a time, which fits my one requirement. But i am not able to get the central image that is visible on screen and zoom it. Although I was able to get the clicked image on screen.
Can someone please tell me where do I need to modify this code and what I need to add in it to get the image that is in center from the images shown on screen and zoom it.
I know that there is no center image on screen according to viewpager and it is just showing three images on screen at a time because of modifications in code.
I have also tried:-
GridView with horizontal scroll
HorizontalScrollView with horizontal linear layout
but viewpager seems to be a better solution, because it stops the scrolling with only three items on screen because of viewpager's inherent properties.
and If someone knows any other method to achieve it, please tell me and I'll try it.
P.S. For anyone who wants the full code, I have added it as an answer, which has zoom capability also. Just few additions in accepted answer. :)
Following code will help you to make a gallery like view which will have center lock. It responds to touch and swipe both. It shows three images on the screen at a time and the center image is zoomed.
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
public class CenteringHorizontalScrollView extends HorizontalScrollView implements View.OnTouchListener {
private Context mContext;
private static final int SWIPE_PAGE_ON_FACTOR = 10;
private int mActiveItem;
private float mPrevScrollX;
private boolean mStart;
private int mItemWidth;
View targetLeft, targetRight;
ImageView leftImage, rightImage;
public CenteringHorizontalScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext=context;
mItemWidth = 100; // or whatever your item width is.
setOnTouchListener(this);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
int x = (int) event.getRawX();
boolean handled = false;
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
if (mStart) {
mPrevScrollX = x;
mStart = false;
}
break;
case MotionEvent.ACTION_UP:
mStart = true;
int minFactor = mItemWidth / SWIPE_PAGE_ON_FACTOR;
if ((mPrevScrollX - (float) x) > minFactor) {
if (mActiveItem < getMaxItemCount() - 1) {
mActiveItem = mActiveItem + 1;
}
}else if (((float) x - mPrevScrollX) > minFactor) {
if (mActiveItem > 0) {
mActiveItem = mActiveItem - 1;
}
}
scrollToActiveItem();
handled = true;
break;
}
return handled;
}
private int getMaxItemCount() {
return ((LinearLayout) getChildAt(0)).getChildCount();
}
private LinearLayout getLinearLayout() {
return (LinearLayout) getChildAt(0);
}
/**
* Centers the current view the best it can.
*/
public void centerCurrentItem() {
if (getMaxItemCount() == 0)
return;
int currentX = getScrollX();
View targetChild;
int currentChild = -1;
do {
currentChild++;
targetChild = getLinearLayout().getChildAt(currentChild);
} while (currentChild < getMaxItemCount() && targetChild.getLeft() < currentX);
if (mActiveItem != currentChild) {
mActiveItem = currentChild;
scrollToActiveItem();
}
}
/**
* Scrolls the list view to the currently active child.
*/
private void scrollToActiveItem() {
int maxItemCount = getMaxItemCount();
if (maxItemCount == 0)
return;
int targetItem = Math.min(maxItemCount - 1, mActiveItem);
targetItem = Math.max(0, targetItem);
mActiveItem = targetItem;
// Scroll so that the target child is centered
View targetView = getLinearLayout().getChildAt(targetItem);
ImageView centerImage = (ImageView)targetView;
int height=300;//set size of centered image
LinearLayout.LayoutParams flparams = new LinearLayout.LayoutParams(height, height);
centerImage.setLayoutParams(flparams);
//get the image to left of the centered image
if((targetItem-1)>=0){
targetLeft = getLinearLayout().getChildAt(targetItem-1);
leftImage = (ImageView)targetLeft;
int width=250;//set the size of left image
LinearLayout.LayoutParams leftParams = new LinearLayout.LayoutParams(width,width);
leftParams.setMargins(0, 30, 0, 0);
leftImage.setLayoutParams(leftParams);
}
//get the image to right of the centered image
if((targetItem+1)<maxItemCount){
targetRight = getLinearLayout().getChildAt(targetItem+1);
rightImage = (ImageView)targetRight;
int width=250;//set the size of right image
LinearLayout.LayoutParams rightParams = new LinearLayout.LayoutParams(width,width);
rightParams.setMargins(0, 30, 0, 0);
rightImage.setLayoutParams(rightParams);
}
int targetLeft = targetView.getLeft();
int childWidth = targetView.getRight() - targetLeft;
int width = getWidth() - getPaddingLeft() - getPaddingRight();
int targetScroll = targetLeft - ((width - childWidth) / 2);
super.smoothScrollTo(targetScroll, 0);
}
/**
* Sets the current item and centers it.
* #param currentItem The new current item.
*/
public void setCurrentItemAndCenter(int currentItem) {
mActiveItem = currentItem;
scrollToActiveItem();
}
}
In your xml add the horizontal scroll view like follow:-
<com.yourpackagename.CenteringHorizontalScrollView
android:id="#+id/HSVImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/Horizontalalternative">
<LinearLayout
android:id="#+id/linearImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
</LinearLayout>
</com.yourpackagename.CenteringHorizontalScrollView>
Define a Linear layout in your activity.
LinearLayout imageGallery;
Then get it as follows:-
imageGallery=(LinearLayout)findViewById(R.id.linearImage);
Now you have to add imageView to your LinearLayout. Here I assume that you have images in your drawable folder and you have made an array of ids of your images that you want to add to gallery. So you can do it via following method in your activity:-
for(int i=0; i<lengthOfImageIdArray; i++){
ImageView image=new ImageView(YourActivityName.this);
image.setBackgroundResource(yourArrayName[i]);
imageGallery.addView(image);
}
You can also set the width of images dynamically, so that they fit every screen, with only little extra effort.
Override setPrimaryItem in your ViewPager and make the center item bigger.
What was the issue with using a HorizontalScrollView with a LinearLayout? If it's centering you may be able to do something similar to this (assuming you've
/**
* A centering HSV loosely based on http://iotasol.blogspot.com/2011/08/creating-custom-horizontal-scroll-view.html
*/
public class CenteringHorizontalScrollView extends HorizontalScrollView implements View.OnTouchListener {
private static final int SWIPE_PAGE_ON_FACTOR = 10;
private int mActiveItem;
private float mPrevScrollX;
private boolean mStart;
private int mItemWidth;
public CenteringHorizontalScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
mItemWidth = 100; // or whatever your item width is.
setOnTouchListener(this);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
int x = (int) event.getRawX();
boolean handled = false;
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
if (mStart) {
mPrevScrollX = x;
mStart = false;
}
break;
case MotionEvent.ACTION_UP:
mStart = true;
int minFactor = mItemWidth / SWIPE_PAGE_ON_FACTOR;
if ((mPrevScrollX - (float) x) > minFactor) {
if (mActiveItem < getMaxItemCount() - 1) {
mActiveItem = mActiveItem + 1;
}
}
else if (((float) x - mPrevScrollX) > minFactor) {
if (mActiveItem > 0) {
mActiveItem = mActiveItem - 1;
}
}
scrollToActiveItem();
handled = true;
break;
}
return handled;
}
private int getMaxItemCount() {
return ((LinearLayout) getChildAt(0)).getChildCount();
}
private LinearLayout getLinearLayout() {
return (LinearLayout) getChildAt(0);
}
/**
* Centers the current view the best it can.
*/
public void centerCurrentItem() {
if (getMaxItemCount() == 0) {
return;
}
int currentX = getScrollX();
View targetChild;
int currentChild = -1;
do {
currentChild++;
targetChild = getLinearLayout().getChildAt(currentChild);
} while (currentChild < getMaxItemCount() && targetChild.getLeft() < currentX);
if (mActiveItem != currentChild) {
mActiveItem = currentChild;
scrollToActiveItem();
}
}
/**
* Scrolls the list view to the currently active child.
*/
private void scrollToActiveItem() {
int maxItemCount = getMaxItemCount();
if (maxItemCount == 0) {
return;
}
int targetItem = Math.min(maxItemCount - 1, mActiveItem);
targetItem = Math.max(0, targetItem);
mActiveItem = targetItem;
// Scroll so that the target child is centered
View targetView = getLinearLayout().getChildAt(targetItem);
int targetLeft = targetView.getLeft();
int childWidth = targetView.getRight() - targetLeft;
int width = getWidth() - getPaddingLeft() - getPaddingRight();
int targetScroll = targetLeft - ((width - childWidth) / 2);
super.smoothScrollTo(targetScroll, 0);
}
/**
* Sets the current item and centers it.
* #param currentItem The new current item.
*/
public void setCurrentItemAndCenter(int currentItem) {
mActiveItem = currentItem;
scrollToActiveItem();
}
}

Categories

Resources