I have a RecyclerView with Images inside. I need to move clicked image to the center of the screen. And there should be no depend on the images's start point, it should move to the center of the screen.
I've tried to do this using XML code - it does't work correct, TranslateAnimation object - it doesn't work correct. In both variants image's movement depends on the images's start position and final points of all images are different.
I don't know how to do this. Please help me)
Try the following code. The code uses Listview, but the same logic can be applied for RecyclerView.
The approach here is to create a new imageview in the parent layout of the listview overlapping the image that was clicked. Then translate the newly created imageview to the center of the screen.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
root = (RelativeLayout) findViewById(R.id.main_root);
listView = (ListView) findViewById(R.id.list);
MyAdapter adapter = new MyAdapter(MainActivity.this, web, imageId);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
ImageView imgView = (ImageView) view.findViewById(R.id.grid_image);
// Get location of window with respect to window.
int location[] = new int[2];
imgView.getLocationInWindow(location);
// Create a new image view overlapping
// the image view that was clicked.
ImageView imgView2 = new ImageView(MainActivity.this);
imgView2.setImageDrawable(imgView.getDrawable());
// To make it overlap, use the location values of
// the clicked image as left and top margin for the
// new image.
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
imgView.getWidth(), imgView.getHeight());
params.leftMargin = location[0];
params.topMargin = location[1] - getStatusBarHeight();
// Add the new image view to the root view of the activity.
root.addView(imgView2, params);
translateToCenter(imgView2, location);
}
});
}
/**
* To translate the new image view to the center of the screen.
* #param view
* #param originalLoc
*/
private void translateToCenter(View view , int originalLoc[])
{
int xMove = root.getWidth() / 2 - view.getWidth() / 2 - originalLoc[0];
int yMove = root.getHeight() / 2 - view.getHeight() / 2 - originalLoc[1];
TranslateAnimation anim = new TranslateAnimation( 0, xMove , 0, yMove );
anim.setDuration(1000);
anim.setFillAfter( true );
view.startAnimation(anim);
}
/**
* To get the status bar height.
* #return
*/
private int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier(
"status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
Related
Here the ImageView is displaying only at one position, after closing the activity the next time the activity is opened the ImageView will be on another position... I want to display the ImageView randomly at diff position on the same activity itself. The image view should appear on one point suddenly the next second ImageView should disappear from that position and appear on the next position. How can i do it?
public class page2 extends ActionBarActivity {
ImageView b2;
int count = 0;
Handler handler = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_page2);
Intent c = getIntent();
String name = c.getStringExtra("t");
Toast.makeText(getApplicationContext(), name, Toast.LENGTH_SHORT).show();
b2 = (ImageView) findViewById(R.id.redball);
AbsoluteLayout.LayoutParams absParams =
(AbsoluteLayout.LayoutParams)b2.getLayoutParams();
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int width = displaymetrics.widthPixels;
int height = displaymetrics.heightPixels;
Random r = new Random();
absParams.x = r.nextInt(width ) ;
absParams.y = r.nextInt(height );
b2.setLayoutParams(absParams);
Animation animation = AnimationUtils.loadAnimation(page2.this, R.anim.fade);
// Animation animation1 = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.activity_move);
b2.startAnimation(animation);
// b2.startAnimation(animation1);
b2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
count = count + 1;
}
});
handler = new Handler();
final Runnable t = new Runnable() {
public void run() {
Intent d = new Intent(getApplicationContext(), Page3.class);
d.putExtra("count", count);
d.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(d);
}
};
handler.postDelayed(t, 4000);
}
#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_page2, menu);
return true;
}
Don't use AbsoluteLayout, Why not use a custom view draw it?
You can achieve this by using Imageview within FrameLayout. Just change the layoutParams of the image to change its position.
As I understand it, you want that each time the activity is opened, so f you dont want to actually view to the user that the ImageView moves, why are you using Animation? You may just dynamically add the ImageView to the activity each time, and each time assign it different Margin attributes.
LinearLayout layout = (LinearLayout) view.findViewById(R.id.linear);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);
params.setMargins(0, 0, 10, 0); //substitute parameters for left, top, right, bottom
ImageView iv = new ImageView(getActivity());
iv.setLayoutParams(params);
iv.setImageResource(R.drawable.yourimage);
layout.addView(iv);
for calucation
ContainerHeight = blinkerContainer.getHeight(); // total height of screen
ContainerWidth = blinkerContainer.getWidth(); //total width
blinkerHeight = blinkView.getHeight();
blinkerWidth = blinkView.getWidth();
minTopMargin = 30;
minLeftMargin = 30;
maxTopMargin = ContainerHeight - blinkerHeight - 30;
maxLeftMargin = ContainerWidth - blinkerWidth - 30;
for positioning
LinearLayout.LayoutParams params = (android.widget.LinearLayout.LayoutParams) blinkView
.getLayoutParams();
params.leftMargin = minLeftMargin
+ new Random().nextInt(maxLeftMargin - minLeftMargin);
params.topMargin = minTopMargin
+ new Random().nextInt(maxTopMargin - minTopMargin);
and you can use AlaramManager for Scheduling
Your solution is almost correct. Unfortunately, it looks like you're restarting the activity from your timer. Instead, you should just trigger the redraw.
This question has a couple of solutions on how to create a recurring timer. The solution with runOnUiThread() should allow you to execute the randomisation and re-displaying of the ImageView.
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();
I am working on an application which has a main screen with a gridview layout.
As it stands currently, I am hardcoding in DP numbers for the height and width of the boxes, which I obviously do not want to do. How to I create code that will determine the users' screen size and match the boxes accordingly so that someone with a large phone like a note will view the same thing as someone on a droid mini? IE, when hardcoding to 500dp on each side, it looks like this:
But my goal is to make it look like this on every screen size:
Currently, this is the Java code I have:
public class ActivityAdapter extends BaseAdapter {
//Array of Icons that will be used as menu choices
public static int[] imageOptions = {
R.drawable.vacation_quota, //Position 0
R.drawable.revenue_deficit, //Position 1
//+ many more options...
};
private Context context;
//Constructor to pass context back to Main class
public ActivityAdapter(Context applicationContext) {
context = applicationContext;
}
//Number of elements to be displayed on the grid
#Override
public int getCount() {
return imageOptions.length;
}
#Override
public View getView(int position, View convertView, ViewGroup arg2) {
ImageView iv;
if(convertView != null){
iv = (ImageView) convertView;
} else {
iv = new ImageView(context);
//Here I have it hard coded to match a 480px width. Here is where I need to change it, just not sure how
iv.setLayoutParams(new GridView.LayoutParams(240, 240));
iv.setScaleType(ScaleType.CENTER_CROP); //Center the cropping
}
//Sets the image to correspond to its position within the array.
iv.setImageResource(imageOptions[position]);
return iv;
}
Any ideas? I think logically I want to figure out the screen dimensions and use them to make the image dimensions match, just not sure how. Research from other threads has not helped a great deal so hoping I can get a simpler answer here with code posting.
You should get the screen width and height. Then use these values to dynamically set height and width for each cell
Try this code-
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle state) {
setContentView(new ViewGroup(this) {
private RelativeLayout[] items = new RelativeLayout[9];
private int width, height, itemWidth, itemHeight;
{
Random r = new Random();
for (int i = 0; i < 9; i++) {
items[i] = new RelativeLayout(getContext());
float[] hsv = new float[] {360 * r.nextFloat(), .50f, .75f};
items[i].setBackgroundColor(Color.HSVToColor(hsv));
addView(items[i]);
// UPDATE ////////////////////////////////////
ImageView image = new ImageView(getContext());
switch (i) {
case 0: // top left
case 1: // top center
case 2: // top right
case 3: // center left
case 4: // center center
case 5: // center right
case 6: // bottom left
case 7: // bottom center
case 8: // bottom right
image.setImageResource(R.drawable.ic_launcher);
break;
}
image.setScaleType(ScaleType.FIT_XY);
image.setLayoutParams(new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT
));
items[i].addView(image);
//////////////////////////////////////////////
}
}
#Override
protected void onMeasure(int wMS, int hMS) {
width = MeasureSpec.getSize(wMS);
height = MeasureSpec.getSize(hMS);
itemWidth = width / 3;
itemHeight = height / 3;
wMS = MeasureSpec.makeMeasureSpec(itemWidth, MeasureSpec.EXACTLY);
hMS = MeasureSpec.makeMeasureSpec(itemHeight, MeasureSpec.EXACTLY);
measureChildren(wMS, hMS);
setMeasuredDimension(width, height);
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
for (int i = 0; i < 9; i++) {
l = itemWidth * (i % 3);
t = itemHeight * (i / 3);
r = l + itemWidth;
b = t + itemHeight;
items[i].layout(l, t, r, b);
}
}
});
super.onCreate(state);
}
}
Output-
Edit-
For creating scrollable grid view see this http://www.androidhive.info/2012/02/android-gridview-layout-tutorial/
I ended up not able to use some of the recommendations here and had to use a deprecated method to retain my app structure. The code specifically that was added to mine was:
iv = new ImageView(context);
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
float width2 = display.getWidth();
int length = (int) (width2/2);
iv.setLayoutParams(new GridView.LayoutParams(length, length));
With this, the height and width would crop to the right size depending on the size of the screen.
First of all sorry for my English. I just began development with android
My problem is:
I create an ImageView in a random position, every time you touch the image, it change its position. When you touch you have a probability (%) that appears another Image in another random position. But my problem is when the second image appear, the first one come back to its "created position" and not keeping position.
The "Bomb" is created well, but then the first image back to created position and not the position it is in the moment.
Thanks all for the help
Example of my test code:
public void start(View view) {
width= 60;
height= 60;
layout = (RelativeLayout) findViewById(R.id.rellayout);
widthLayout = layout.getWidth();
heightLayout = layout.getHeight();
r = new Random();
x = r.nextInt(widthLayout - 60);
y = r.nextInt(heightLayout - 60);
imagen = new ImageView(this);
imagen.setImageResource(R.drawable.led_circle_green);
RelativeLayout.LayoutParams paramss = new RelativeLayout.LayoutParams(
60, 60);
paramss.leftMargin = x;
paramss.topMargin = y;
imagen.setAdjustViewBounds(true);
layout.addView(imagen, paramss);
Animation aparecer = AnimationUtils
.loadAnimation(this, R.anim.aparecer);
imagen.startAnimation(aparecer);
imagen.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// your code here
push();
}
});
public void push() {
createBomb();
move();
}
public void createBomb() {
r = new Random();
int proba = r.nextInt(100);
if (proba < 50) {
x = r.nextInt(widthLayout - 60);
y = r.nextInt(heightLayout - 60);
bomb = new ImageView(this);
bomb.setImageResource(R.drawable.bomb);
RelativeLayout.LayoutParams paramss = new RelativeLayout.LayoutParams(
60, 60);
paramss.leftMargin = x;
paramss.topMargin = y;
bomb.setAdjustViewBounds(true);
layout.addView(bomb, paramss);
}
}
public void move() {
r = new Random();
int proba = r.nextInt(100);
if (proba < 10) {
ximg = r.nextInt(widthLayout - width);
yimg = r.nextInt(heightLayout - height);
imagen.layout(ximg, yimg, ximg + width, yimg + height);
}
}
layout method does not applies persistent changes to a view state. Set new layout params to image view, which will specify it's new position (do not use layout method).
When you add new ImageView2 RelativeLayout decides to relayout its childs and resets ImageView1 position.
Read this.
I am trying to make a popup window appear above/below an item that is clicked inside of a ListView.
However, the problem is that the View that is coming in from the OnItemClick method is only giving me its X & Y values relative to the ListView itself. I also checked the ListView and that is also giving me x=0 y=0 despite the fact that there are other views above it.
I ran through all the values in hierarchyviewer, but didn't see the values I was looking for. (And not I'm having major problems getting it to work again).
Any advice?
#Override
public void onListItemClick(ListView listView, View view, int position, long id) {
LayoutInflater inflater = getLayoutInflater(null);
PopupWindow quickRail = new PopupWindow(
inflater.inflate(R.layout.quanitity_controls, null), view.getMeasuredWidth(),
view.getMeasuredHeight());
int[] location = {
0, 0
};
// This doesn't place this window right on top of the view
quickRail.showAtLocation(view, Gravity.CENTER, 0, location[1]);
}
Both items in the list are making the Popup appear in the same place.
This should work
//Activity windows height
int totalHeight = getWindowManager().getDefaultDisplay().getHeight();
int[] location = new int[2];
v.getLocationOnScreen(location);
The location array should have the x and y values of the view.
'v' is the view object passed on the onItemClickListener.
Im adding some parts I used for my project. It might be helpful. I had an actionbar on the top of the listview and this code seemed to work fine.
The requirement was to bring a small menu either on top or below a list item. So when an item is selected, I check if the selected list item is in the upper half of the screen, if so put the menu below the list item otherwise put it on top of the list item.
Here's the code
ListItem click code
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position
, long id) {
showQuickActionMenu(position,view);
}
});
private void showQuickActionMenu(int pos, View v){
LayoutInflater inflater =
(LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//This is just a view with buttons that act as a menu.
View popupView = inflater.inflate(R.layout.ticket_list_menu, null);
popupView.findViewById(R.id.menu_view).setTag(pos);
popupView.findViewById(R.id.menu_change_status).setTag(pos);
popupView.findViewById(R.id.menu_add_note).setTag(pos);
popupView.findViewById(R.id.menu_add_attachment).setTag(pos);
window = PopupHelper.newBasicPopupWindow(TicketList.this);
window.setContentView(popupView);
int totalHeight = getWindowManager().getDefaultDisplay().getHeight();
int[] location = new int[2];
v.getLocationOnScreen(location);
if (location[1] < (totalHeight / 2.0)) {
PopupHelper.showLikeQuickAction(window, popupView, v
, getWindowManager(),0,0,PopupHelper.UPPER_HALF);
} else {
PopupHelper.showLikeQuickAction(window, popupView, v
, getWindowManager(),0, 0,PopupHelper.LOWER_HALF);
}
}
This the PopupHelper class I use
public class PopupHelper {
public static final int UPPER_HALF = 0;
public static final int LOWER_HALF = 1;
public static PopupWindow newBasicPopupWindow(Context context) {
final PopupWindow window = new PopupWindow(context);
// when a touch even happens outside of the window
// make the window go away
window.setTouchInterceptor(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_OUTSIDE) {
window.dismiss();
return true;
}
return false;
}
});
window.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
window.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
window.setTouchable(true);
window.setFocusable(true);
window.setOutsideTouchable(true);
window.setBackgroundDrawable(
new ColorDrawable(android.R.color.darker_gray));
return window;
}
/**
* Displays like a QuickAction from the anchor view.
*
* #param xOffset
* offset in the X direction
* #param yOffset
* offset in the Y direction
*/
public static void showLikeQuickAction(PopupWindow window, View root,
View anchor, WindowManager windowManager, int xOffset
,int yOffset,int section) {
//window.setAnimationStyle(R.style.Animations_GrowFromBottomRight);
int[] location = new int[2];
anchor.getLocationOnScreen(location);
Rect anchorRect = new Rect(location[0], location[1], location[0] +
anchor.getWidth(), location[1] + anchor.getHeight());
root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
int rootWidth = root.getMeasuredWidth();
int rootHeight = root.getMeasuredHeight();
int screenWidth = windowManager.getDefaultDisplay().getWidth();
int screenHeight = windowManager.getDefaultDisplay().getHeight();
int xPos = ((screenWidth - rootWidth) / 2) + xOffset;
int yPos = anchorRect.top - rootHeight + yOffset;
xPos = (screenWidth - rootWidth);
if(section == UPPER_HALF){
yPos = anchorRect.top + anchor.getMeasuredHeight();
} else {
yPos = anchorRect.top - rootHeight;
}
window.showAtLocation(anchor, Gravity.NO_GRAVITY, xPos, yPos);
}
}
for those who stick on this issue
try use this code snippet
popWindow.showAsDropDown(v);//v is your listview or recyclerview item Element that clicked.
hope this help.
Try this and see if it works..
private void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = 0;
int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST);
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
totalHeight += listItem.getMeasuredHeight();
}
}
//here listItem.getMeasuredHeight() will get u the height of each list item...U can get ur y position by height*clickedPosition