Im working on my circular list view. I implement almost all functionality, but i have some problem. When my activity starts my listView looks like: https://dl.dropbox.com/u/44444463/Screenshot_2013-02-28-14-37-17.png
But it is not right. It should looks like: https://dl.dropbox.com/u/44444463/Screenshot_2013-02-28-14-37-44.png
Here is my problem.
When activity starts its look like in first screenshot. If i touch any element in listView, or scroll it (if there is a lot of elements) it baceme like in screenshot2. Exactly what i need.
How can i take image like in scrennshot 2 in activity start?
I overrited method #Override public void onScroll(..) in OnScrollListener of my listView, where i aplly all paddings:
// int x = 30;
for (int i = 0; i < visibleItemCount; ++i)
{
View v = listView.getChildAt(i);
if (v != null)
{
LinearLayout rl = (LinearLayout) v.findViewById(R.id.rl);
float sin = (float) (v.getTop() + v.getHeight() / 2 - centerOfCircle) / radius;
double angle = Math.asin(sin);
int x = (int) (-dXRow + radius * Math.cos(angle));
if (x < 0)
x = 0;
Log.d("MN", "setPadding: " + x);
rl.setPadding(x, 0, 0, 0);
}
}
Really sorry for my Engish
You should set starting peddings in the getView() method of your listView's adapter. And then recompute them onScroll() as you need.
OnScroll method isnt invoked when the listView appear, only when you scroll it.
Related
Hey everyone So I have created a grid on stage using the code below. Everything works fine and the grid is created. Only problem is when i change the columns and rows value to a higher value the grids position changed offset to the center of the stage. I want it to be when i change the values and more columns etc are added the Grid stays dead center.
Also it seems that the grid expands to the positive x axis from the top left hand corner of the grid.
What can I do to fix this?
public function geniusMatchEngine()
{
//Instantiate Variables
nSquares = 0;
//Movie clips
_gridContainer = new MovieClip();
stage.addChild(_gridContainer);
createGrid();
//Add Listeners
stage.addEventListener(Event.ENTER_FRAME, logicHandler);
}
private function logicHandler(e:Event):void
{
}
private function createGrid():void
{
for (var gy:int = 0; gy < rows; gy++)
{
for (var gx:int = 0; gx < columns; gx ++)
{
var _grid:mcGrid = new mcGrid();
_grid.x = (stage.stageWidth / 2) + _grid.width * gx;
_grid.y = (stage.stageHeight / 2) + _grid.height * gy;
_gridContainer.addChild(_grid);
_grid.addEventListener(MouseEvent.CLICK, tapGrid);
}
}
}
private function tapGrid(e:MouseEvent):void
{
trace("CLICKED");
e.currentTarget.destroy(); //Destroy current target
}
private function centerGrid(gCenter:MovieClip):void
{
gCenter.x = (stage.width / 2) - (gCenter.width / 2); // center horizontally.
gCenter.y = (stage.height / 2) - (gCenter.height / 2); // center vertically.
}
To center something on the stage do:
private function centerThis(s:<Type>):void{
s.x = stage.width / 2 - s.width / 2; // center horizontally.
s.y = stage.height / 2 - s.height / 2; // center vertically.
}
Then with your grid you can do:
centerThis(_grid);
Note: make sure to replace <Type> with whatever makes sense. In this case it could be mcGrid but to make it more generic so you can use this function on any movie clip or Sprite use MovieClip or Sprite.
update
Since you seem a little confused about scope, I'll use your specific case as an example.
//Variables
private var rows:int = 2;
private var columns:int = 2;
for (var gy:int = 0; gy < rows; gy++)
{
for (var gx:int = 0; gx < columns; gx ++)
{
var _grid:mcGrid = new mcGrid();
_grid.x = (stage.stageWidth / 2) - _grid.width / 2;
_grid.y = (stage.stageHeight / 2) - _grid.height / 2;
stage.addChild(_grid);
}
}
I thought the _mcGrid was a prefabricated grid. I'm now seeing that it is probably just one cell in the grid (maybe change the class name to _mcGridCell... less confusing). Forget trying to place the cells relative to the stage center. Add them to a parent Sprite (or MovieClip if you prefer) and then center that Sprite (movieClip) with my centerThis formula. This is the beauty of display object containers.
update
Ok. When you center the grid container, everything in the container goes with it. So no need to also try to center the cells in the grid as you have done.
grid.x = (stage.stageWidth / 2) + _grid.width * gx;
should just be
grid.x = _grid.width * gx;
At a given pixel location, there is a view. I have the coordinates of the pixel. How to find the id of a view at a given coordinate ?
If you are inside of ViewGroup:
int count = viewgroup.getChildCount();
for (int i = 0; i < count; i++)
{
View view = viewgroup.getChildAt(i);
if (view.getX() == theX && view.getY() == theY)
return view.getId()
}
EDIT (kcoppock): within the for loop, I'd do something like this:
View view = viewgroup.getChildAt(i);
if(!view.getVisibility() == View.VISIBLE) continue;
int[] location = {0, 0};
view.getLocationOnScreen(location);
int right = location[0] + view.getWidth();
int bottom = location[1] + view.getHeight();
Rect bounds = new Rect(location[0], location[1], right, bottom);
if(bounds.contains(coordinatesX, coordinatesY)) return view.getId();
I think something like this should work:
Walk your view hierarchy to find child views (i.e. those with no sub-views) that are Visible.
use View.getLocationOnScreen() on your views to retrieve their location (the top/left window coordinate)
use getMeasuredWidth() / getMeasuredHeight() to get the view width and height
see if your pixel coordinate falls within this rectangle
i'm using RealViewSwitcher I got from this site.
It works perfectly on my code, but I don't have any idea how to set the initial current screen to second or third screen.
the method setCurrentScreen(int) doesn't affect anything and if I change the for loop inside the onLayout() method from for (int i = 0; i < count; i++) {...} into for (int i = 1; i < count; i++){...} It does starts in page two, but you can't go to page one.
Any idea how to start on page two?
The local solution is to add new class method. If you want start on second page - just call snapToScreenFast(2).
public void snapToScreenFast(int whichScreen) {
if (!mScroller.isFinished())
return;
whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));
mNextScreen = whichScreen;
final int newX = whichScreen * getWidth();
final int delta = newX - getScrollX();
mScroller.startScroll(getScrollX(), 0, delta, 0, 0);
invalidate();
}
is it possible to find the View that is displayed at a given absolute x/y pixel coord?
Edit: I found a suitable Solution that works great:
private View findViewByCoord(float x, float y){
TextView textView = null;
int[] location = new int[2];
int width = 0;
int height = 0;
for(int reference : cardReference){
textView = (TextView) findViewById(reference);
textView.getLocationOnScreen(location);
width = textView.getWidth();
height = textView.getHeight();
if(location[0] <= x && x <= (location[0] + width) && location[1] <= y && y <= (location[1] + height)){
Log.i("Test", "Card " + textView.getText() + " is pointed");
return textView;
}
}
return null;
}
Where cardReference is an array of integer to Resources (in my case 20 TextViews arranged in a 4 x 5 Matrix):
int[] cardReference = new int[]{R.id.card1_1, R.id.card1_2, R.id.card1_3, R.id.card1_4,
R.id.card2_1, R.id.card2_2, R.id.card2_3, R.id.card2_4,
R.id.card3_1, R.id.card3_2, R.id.card3_3, R.id.card3_4,
R.id.card4_1, R.id.card4_2, R.id.card4_3, R.id.card4_4,
R.id.card5_1, R.id.card5_2, R.id.card5_3, R.id.card5_4};
To speed up performance i would consider to use an array of TextViews then call findViewById() in every Loop.
One 'solution' would be to loop through the parent view's children and check the getLeft() and getTop() coordinates against the X and Y coordinates of your choice. If there is a match, you have your view.
I'd like to hear other alternatives though.
Edit: You'd also have to work out the height/width of the view too in relation to the left and top coordinates given to see if your coordinates are within that range.
I've a custom view which draws a running graph - some magnitude versus time. Now I want to implement a custom scroll bar for this so that I can view past data which are offscreen. The data is available to me. I just need the %offset selection by the user.
Any help/suggestions on implementation would be v helpful.
Code Snippet from my Custom view's onDraw method
public void onDraw(Canvas canvas) {
int totalpts = data.size();
scale = getWidth() / (float) maxpoints;
List<Data> display = new ArrayList<Data>();
int initial = 1;
if (totalpts > maxpoints) {
initial = totalpts - maxpoints;
display = data.subList(initial, data.size() - 1);
} else {
display = data;
}
int size = display.size();
Data start = null;
float x1 = 0, x2 = 0, x = 0;
if (size > 1) {
x1 = getWidth();
start = display.get(display.size() - 1);
for (int i = display.size() - 1; i >= 0; i--) {
Data stop = display.get(i);
x = x1;
x1 -= (stop.x * scale / 1000);
canvas.drawLine(x, start.Y, x1, stop.Y, paint1);
start = stop;
}
}
}
Try putting your custom control inside a HorizonatalScrollView (assuming you want it to scroll horizontally), use ScrollView otherwise), setting the width of your control to "WRAP_CONTENT", and the HoizontalScrollView to "FILL_PARENT". Without seeing the code for your custom view, it's difficult to know whether you might need to do some tinkering with the width calculation to get this working.