how to get a sibling of a clicked view? - java

I have 2 buttons
I want only one of them to be selected at most at a time.
how can i find a view's sibling while in onClick ?
I have tried:
siblingView = v.getParent().findViewById(R.id.rightBtn);
but parentView has no findViewById method.
is it possible to get an ancestor view (even not direct) ? which is view for sure?

getParentView return type is an interface ViewParent
you can test if it is actually a View (or do not test, if you are sure), and downcast it to View.

If I understand this correctly, you need some kind of tabs, not two buttons.
Check this out for more details about how to implement that kind of behavior, using tabs not buttons.

Related

Java - Android - view.getContext() meaning

Hello i have just started learning android application development and i am watching a lot of tutorials but none of them really describe step by step so my question is :
i have created a simple app which contains on TextView one EditText and one Button
i have added android:onClick="onButtonClick" to my Button so it will trigger the onButtonClick method , now , i would like it to print out the userinput from EditText so what i did is :
public void onButtonClick(View v){
Toast.makeText(v.getContext(), email.getText().toString(), Toast.LENGTH_SHORT).show();
}
but why the method has to contain the View v ? where is it passed from ? and what does it contain ? it contains the button which i clicked ? and what does the v.getContext() do? why my app does the same when replacing the v.getContext() with this ?
That are many questions at once, but I try to answer them one by one.
but why the method has to contain the View v ? where is it passed from ? and what does it contain ?
Consider the documentation of View.OnClickListener:
View: The view that was clicked.
So you are correct in your assumption that it is the View that has been clicked.
and what does the v.getContext() do?
The first parameter of the Toast#makeText method is a Context. Basically the Context is a container of global information in an Android application. The Toast needs it to retrieve information to show itself.
why my app does the same when replacing the v.getContext() with this ?
I assume your method resides in an Activity. An Activity is a subclass of Context and can be used as a parameter.
If you click a button then View is passed. ViewGroup is a group of View example LinearLayout, Relative Layout, FrameLayout,etc. View is a part of ViewGroup. According to Official Documentation, A View occupies a rectangular area on the screen and is responsible for drawing and event handling. View is the base class for widgets, which are used to create interactive UI components (buttons, text fields, etc.). The ViewGroup subclass is the base class for layouts, which are invisible containers that hold other Views (or other ViewGroups) and define their layout properties.
I hope you understand well about what is View and ViewGroup!!

How to understand a fragment?

So I have re-write it.
The problems are:
If a fragment is declared in xml, then you can't call replace on it. Why?
If you want to put a fragment into a FrameLayout(id, frame_layout), then call
add(R.id.frame_layout, fragment) will result in "No View exist Error". There is a way around this by calling add(android.R.id.content, fragment).
The problem is, what if the R.id.frame_layout isn't the base layout for your activity?
Also, in dynamic fragment dispatch(using replace and add), maybe only one container could contain one fragment rather than two?
I have browsed a lot...
Q1. If a fragment is declared in xml, then you can't call replace on it. Why?
Because that's a static fragment. Android system would always stick to it. There is no way to remove or replace it. Any new fragment that's "add" or "replace" on the same id would be placed on top of each other.
Q2 If you want to put a fragment into a FrameLayout(id, frame_layout), then call add(R.id.frame_layout, fragment) will result in "No View exist Error". There is a way around this by calling add(android.R.id.content, fragment). The problem is, what if the R.id.frame_layout isn't the base layout for your activity?
This is not true. Depending on situations. Generally speaking, the id in the function call "add(id)" only means the container of the fragment or the view which is to be replaced by fragment. android.R.id.content represents the buttom layer of the views in the activity.
Also, in dynamic fragment dispatch(using replace and add), maybe only one container could contain one fragment rather than two?
Well, it depends. Just for the sake of clarity(if you want co-workers to understand your code), it's good habbit to make sure that only one container contains one fragment. That's dynamic fragment, not the rule of static fragment.

Why does my custom AdapterView not measure itself in OnMeasure

I have a 2 dimensional ListView, much like a list of carousels in iOS.
However when OnMeasure() is called on each HorizontalListView I don't understand the proper way to SetMeasuredDimensions(). At the moment I am checking for a child and matching the childs MeasuredHeight.
I don't actually even need to do anything special so I would rather not override the OnMeasure() and just leave the layoutparams as wrap_content.
I don't know if this is correct as in another project OnMeasure gets called before OnLayout therefore I haven't actually Added or Measured any children yet (which I do in OnLayout() ). I also don't know how to force another Measure pass in hope that a layout pass has been.
Question is. How do I use the HoriztonalListView LayoutParams of wrap_content properly?
I have supplied the project Here

Multi-level ExpandableListView in Android

I'm trying to create a category tree from a given unknown-size nor level list of categories. So I'm trying to create a general expandable list which can contain 2+ number of levels.
The general idea is to add to every child who has childs another ExpandableListView in it's layout. The problem is that the second level wont open, it looks like it rendered it over the child or something. Here's some screen-shots of the result:
Here's how it's look like before opening
And after opening the first option: (It's supposed to be empty)
And now open the second one: (Has 4 childs and one of them have childs of his own)
As you can see the third option looks like it's been rendered another option or something on it, after clicking to open it:
It's does nothing except change the state of the arrow. At least it tries to open it...
Here's the code:
CatAdapter.java: (extends BaseExpandableListAdapter)
http://pastebin.com/6yUTkMbJ
Category.java:
http://pastebin.com/E7yWwpna
catitem.xml:
http://pastebin.com/G5MPT3Ua
The usage:
http://pastebin.com/Wk0FqJhn
Sorry for the long question, I was trying to be clear as possible.
Thanks in advance! Sorry for my bad english!
Edit:
I ended up making a custom view for this task, thank you all for your answers!
I believe the problem is in your getChildView() method:
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
convertView = inflater.inflate(R.layout.catitem, parent, false);
TextView textView_catName = (TextView)convertView.findViewById(R.id.textView_catName);
Category current = categories.get(groupPosition).childs.get(childPosition);
textView_catName.setText(groupPosition + " , " + childPosition);
if(current.childs.size() > 0 ) {
ExpandableListView elv = new ExpandableListView(context);
elv.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.WRAP_CONTENT, AbsListView.LayoutParams.WRAP_CONTENT));
elv.setAdapter(new CatAdapter(context, current.childs));
((ViewGroup)convertView).addView(elv);
}
return convertView;
}
When you encounter an 'expandable' child, you are still inflating R.layout.catitem and adding your new elv to it. Since the catitem is a RelativeLayout and you don't add any parameters for alignment, each view is placed at the top-left corner, overlaying whatever else is there.
You may want to try changing R.layout.catitem to have a vertical LinearLayout as its root. This should prevent them from overlapping the child's title, but I can't guarantee that the children's children will not still overlap. It's an easy change, though, and worth a shot.
Also, from the docs for ExpandableListView:
Note: You cannot use the value wrap_content for the android:layout_height attribute of a ExpandableListView in XML if the parent's size is also not strictly specified (for example, if the parent were ScrollView you could not specify wrap_content since it also can be any length. However, you can use wrap_content if the ExpandableListView parent has a specific size, such as 100 pixels.
That says "in XML", so I'm not sure if it means to apply to code or not. It seems to me that they'd use the same mechanism, so it might be worth looking into. I'm not sure how you'd go about setting a maximum size for the parent. You may be able to measure the size of one item, and multiply by the number of children. You'd have to take margins/separators into account, so it may not be simple.
If that doesn't work, you may need to roll your own ViewGroup directly. It shouldn't be too hard to implement it from scratch, just don't forget to try to take advantage of view recycling(which your current method doesn't do anyway).
I was have same situation where I had to use ExpandableList and at each level I needed to have groupPosition and childPosition but using multi-level ExpandableList, It was not possible to get accurate groupPosition at second level data. So that, I used another approach. I have given a demo link which I used in a project.
1) In this library, you need to bind parent child relation in advance before you bind your actual data.
2) In your Layout, top most layout must be LinearLayout. Please refer header.xml, groups.xml and childs.xml in demo link.
Demo Link: MultiLevelTreeView
Thanks.

How to get getSelectedView() to work in GridView?

I have a GridView in a layout. It is populated with Foo views by the activity using a extended BaseAdapter.
When I select an item in this grid it gets orange tinted (thus selected). That's nice. But I want to access this selection from outside the GridView and it's parent activity: from within another View higher in the layout hierarchy. I therefor call upon gridView.getSelectedItem(). However it always returns null.
How could I get this to work?
"Selection" doesn't mean the same thing in AndroidOS as it does in other UIs. In particular, there isn't any "selected item" when you're in touch mode. You probably need to use a click listener instead of relying on there being a "selected item". See this article for details.
You can use the following to get the view:
View childView = gridView.getChildAt(position - gridView.getFirstVisiblePosition());

Categories