I'm trying to create a One-armed Bandit app.
I have created an animation xml file to go through multiple images. When a button is clicked, the animation stops.
My question is how to compare the picture that one animation stopped on with that of another? So far I've tried something like this:
if(wheel1.getBackground().getConstantState().equals(wheel2.getBackground().getConstantState())) matches++;
Any help is appreciated.
you must be starting the animation with .animationStart()
just use .onAnimationStop() and it will trigger the event automatically.
A View should not maintain application logic, the controller (your hosting Activity or Fragment) should.
That said, to achieve what you want use View.setTag() to apply a logical description of each View to it.
Then when stopping animation, loop through all Views you have and get their position on screen, get the Views mostly visible in each column of your bandit machine and compare their tags (View.getTag())
for example, if the items animate vertically use below method to determine where the bandit stopped.
//the area where to compare views
int BOUND_TOP, BOUNT_DOWN;
//your content view
ViewGroup rootLayout;
//method to get information about what is visible
public List<Object> getVisibleViewTags() {
List<Object> list = new LinkedList<>();
int count = rootLayout.getChildCount();
for (int pos = 0; pos < count; pos++) {
View child = rootLayout.getChildAt(pos);
float translationY = child.getTranslationY();
if (translationY > BOUND_TOP && translationY < BOUND_DOWN) {
list.add(child.getTag());
}
}
return list;
}
Now you just need to attach information about a view as tag to it.
example:
view.setTag("view_apples");
or
view.setTag("view_bananas");
Related
I want to get all views inside of an activity. like;
ArrayList<View> views = new Arraylist<>();
views.addAll(getAllViewsFromActivity());
what I want is "getAllViewsFromActivity()" function. I clearly want to get all the views even a single button. But I couldn't find any clear answer.
For the progress, it must be like this:
MainView : getWindow().getDecorView()
- -
RelativeLayout
- -
Button LinearLayout
-
TextView
How can I get this tree in Android programmatically? and also lets assume that I got this tree, Can I also identify the types of them like: view instanceof Button ?
the view you want to get is clear. so you can use the parent view(such as LinerarLayout) to get the children. so you can try this:
int count = parent.getChildCount();
for(int i =0; i< count;i++){
View child = parent.getChildAt(i);
//here you can to chage the view some proper.
//if you only want to change the background color, it belongs to view, don't
// need to cast.
}
So essentially, I have a recyclerview that has a list of levels. But essentially, I want certain items to have a black colored background to suggest that they are not locked yet.(kind of like in video games)
my current method:
#Override
public void onBindViewHolder(BracketsAdapter.ViewHolder viewHolder, int position) {
// Get the data model based on position
Bracket bracket = bracketsList.get(position);
int color = UserPreferences.getInstance().getBracket();
// Set item views based on your views and data model
TextView textView = viewHolder.nameTextView;
textView.setText(bracket.toString());
Log.d("Bracket level", ""+bracket.getId());
if(color < bracket.getId()) {
textView.setBackgroundResource(R.color.black); // suggests level is locked
}
}
The issue with this method, is that it works initially but the moment I scroll down and back up, items that should not be colored end up being colored. Why is this? Is there a better way of implementing this?
Recycle view always reuses the old view so you are getting that problem, To solve the problem, you should set color every time calling bindViewHolder, So try to do like this,
if(color < bracket.getId()) {
textView.setBackgroundResource(R.color.black); // suggests level is locked
} else {
textView.setBackgroundResource(R.color.defaultcolor); // default color
}
this will work fine.
Part of application I'm currently working on act exactly as android shell, shows several pages filled with icons with text labels. User could slide between pages to find needed element. I'm using PagerView with GridView in each page.
Content of each page should fit exactly of visible area, no scroll. The question how to calculate number of icons on each page?
The issue next, I can't call pagerView.getHeight(), I'll have 0 in result because actual layout calculation wasn't executed yet.
UPDATED:
Seems I wasn't able to describe my problem well, I'll try to provide more simple case, suppose I do have activity with status bar at the top and some button bar at the bottom, both fixed height. Whole remaining area in the middle is used by GridView.
Grid view should show rectangular icons, and what I need to calculate is how many icons it could show without scroll (because remaining icons will be shown on next activity).
You can try something like:
public int countElements(ViewGroup group) {
int count = 0;
for (int i = 0; i < group.getChildCount(); i++) {
View v = layout.getChildAt(i);
Class c = v.getClass();
if (c == *Icon*) {
count++;
}
}
return count;
}
In case you have inner views you can check if c is a GroupView and call the method recursively.
As for your second issue, try using this in onCreate:
private void calculateSize(int height, int width){
int rows = Math.floor(height/imageHeight);
int columns = Math.floor(width/imageWidth);
//do something with numbers
}
ViewTreeObserver vto = pagerView.getViewTreeObserver();
if(vto.isAlive()){
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
vto.removeGlobalOnLayoutListener(this);
calculateSize(gridView.getHeight(), gridView.getWidth());
}
});
}
I have a gridview that is made of of 31 cells. A user can select any combination of cells and then click on a button to save their selections. Once they click the save button a dialog box appears and asks them what they want to do next. Within this dialog is a edit text view. When the user clicks inside the edit text box the keyboard appears. When this happens only 21 of the 31 cells are visible on the screen and when I try to call the getChildrenCount() method of GridView class I only see 21 children. Can someone explain why this happens and what I can do to eliminate this issue? I have attached images in hopes that clarifies the issue. Below I have pasted a snippet of code where I am trying to get the child count of the gridview.
protected Set<String> getSelectedFrequencies() {
Set<String> selectedFrequencies = new HashSet<String>();
for(int i = 0; i < gridView.getChildCount(); i++) {
ViewGroup gridChild = (ViewGroup) gridView.getChildAt(i);
for(int k = 0; k < gridChild.getChildCount(); k++) {
if( gridChild.getChildAt(k) instanceof Button ) {
if(gridChild.getChildAt(k).isSelected()) {
selectedFrequencies.add(gridChild.getChildAt(k).getTag().toString());
}
}
}
}
return selectedFrequencies;
}
There is nothing really special about the code.
Are you using a softInputMode of pan or resize? With pan that will never happen. With resize, it could be that only 21 fit on screen, so the gridView creates only 21 children and does view swapping when you scroll. In case you didn't know, listview and gridview only create as many views as are needed to fit on the screen. When you scroll it just loads data for the new positions into the existing views.
I am using it, but it always returns 0, even though I have scrolled till the end of the list.
getScrollY() is actually a method on View, not ListView. It is referring to the scroll amount of the entire view, so it will almost always be 0.
If you want to know how far the ListView's contents are scrolled, you can use listView.getFirstVisiblePosition();
It does work, it returns the top part of the scrolled portion of the view in pixels from the top of the visible view. See the getScrollY() documentation. Basically if your list is taking up the full view then you will always get 0, because the top of the scrolled portion of the list is always at the top of the screen.
What you want to do to see if you are at the end of a list is something like this:
public void onCreate(final Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.main);
// The list defined as field elswhere
this.view = (ListView) findViewById(R.id.searchResults);
this.view.setOnScrollListener(new OnScrollListener() {
private int priorFirst = -1;
#Override
public void onScroll(final AbsListView view, final int first, final int visible, final int total) {
// detect if last item is visible
if (visible < total && (first + visible == total)) {
// see if we have more results
if (first != priorFirst) {
priorFirst = first;
//Do stuff here, last item is displayed, end of list reached
}
}
}
});
}
The reason for the priorFirst counter is that sometimes scroll events can be generated multiple times, so you only need to react to the first time the end of the list is reached.
If you are trying to do an auto-growing list, I'd suggest this tutorial.
You need two things to precisely define the scroll position of a listView:
To get current position:
int firstVisiblePosition = listView.getFirstVisiblePosition();
int topEdge=listView.getChildAt(0).getTop(); //This gives how much the top view has been scrolled.
To set the position:
listView.setSelectionFromTop(firstVisiblePosition,0);
// Note the '-' sign for scrollTo..
listView.scrollTo(0,-topEdge);