In my app the user spins a carousel. On the selected Item I need to display a separate xml view for each item. The carousel is visibile at all time at the bottom with the view visible in the top half. I think that there is a better way than to use fragments. Any ideas? The following code is not functional as of now but I think an inflator may be the way to go but to get it done is troubling me. After case0 there is case1-case5.
carousel.setOnItemSelectedListener(new OnItemSelectedListener(){
public void onItemSelected(CarouselAdapter<?> parent, View view,
int position, long id) {
switch(position){
case 0:
final View firstview;
LayoutInflater inflater = (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
firstview = inflater.inflate(R.layout.selected_item, null);
break;
case 1:
In case anyone else runs into this problem I solved it:
LayoutInflater inflater = (LayoutInflater) CarouselActivity.this.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
LinearLayout inflateView = (LinearLayout) findViewById( R.id.InflateParent );
View nextView = null;
switch(position){
case 0:
System.out.println("Case 0");
inflateView.removeAllViews();
nextView = inflater.inflate( R.layout.nextview, null );
inflateView.addView(nextView);
Related
the PRJ contains :
Frag_Settings which has the ExpandableListView, using a custom adpater I name it Frag_Settings_Adapter listAdapter.
the expandable groups are 5 and are static (aka predefined). Each of group accommodate a different view. One of these views has listview, which also implements a custom adapter (takes records from dbase)...
so lets see, what I have wrote for the moment, at expandable Frag_Settings_Adapter :
#Override
public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
LayoutInflater inflater = null;
switch (groupPosition) {
case 0:
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.frag_settings_row_detail_01_cities, null);
break;
case 1:
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.frag_settings_row_detail_02_categories, null);
//raise event to parent
if (listener_02_categories != null)
listener_02_categories.fill_with_data(convertView);
break;
}
return convertView;
}
when group is 2, inflate the view + raise an event to fragment with the view! (is this good?)
then at fragment, onActivityCreated, when setup expandable_listview :
listAdapter = new Frag_Settings_Adapter(getActivity(), listDataHeader, listDataChild);
listAdapter.setListener(new Fill_02_Categories_Listener() {
#Override
public void fill_with_data(View convertView) {
////////////////////////////////////////////////
//////////////listview 02 - categories
lstv = (ListView) convertView.findViewById(R.id.frag_settings_row_detail_categories_lstv);
Frag_Settings_Categories_LIST = new ArrayList<Frag_Settings_Categories>();
lstv.setOnItemClickListener(this);
lstv_adapter = new Frag_Settings_Categories_Adapter(getActivity(), Frag_Settings_Categories_LIST);
lstv.setAdapter(lstv_adapter);
CategoriesDatasource categories_datasource = new CategoriesDatasource(getActivity());
for (Categories d : categories_datasource.getAllCategoriess()) {
Frag_Settings_Categories_LIST.add(new Frag_Settings_Categories(d.getid(),d.getcategory_name(),false));
}
lstv.setAdapter(lstv_adapter);
}
});
// setting list adapter
expListView.setAdapter(listAdapter);
-this one working but I have somehow increase the height of expandable group 2 because now I can see only 1listview item... :(
-over all, is there any way to achieve this in more easier way?
-the method I follow is correct?
No way^ too many problems with that way....
I discover a manual solution, once as I said the views are static https://tsicilian.wordpress.com/2013/09/02/android-tips-expandablecollapsible-views/
I'm an Android newbie. I want to create an expandable ListView where 1 row has custom info that has to be specified in the manin thread instead of being hardcoded in a layout.
I want to have an image and 2 textviews in it. I think I will need a custom layout file, but I'm not sure where to make a call for it in my code. Please assist.
What follows is my GropView fxn inside my custom adapter. I want case 0 to load a custom layout file
public View getGroupView(int groupPosition, boolean arg1, View convertView,
ViewGroup arg3) {
String laptopName = (String) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.group_item, null);
}
TextView item = (TextView) convertView.findViewById(R.id.laptop);
item.setTypeface(null, Typeface.BOLD);
item.setText(laptopName);
this.context = (Activity) context;
switch (groupPosition) {
case 0:
convertView.setBackgroundColor(this.context.getResources()
.getColor(R.color.dark_blue));
convertView.inflate(R.layout.first_row_layout, 0, arg3);
break;
case 1:
convertView.setBackgroundColor(this.context.getResources()
.getColor(R.color.purple));
break;
case 2:
convertView.setBackgroundColor(this.context.getResources()
.getColor(R.color.green));
break;
default:
break;
}
return convertView;
}
The position in your code where you define the layout for your group items is this:
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.group_item, null);
}
In your case you are using the layout R.layout.group_item for your group items. If you want to load different layouts for each group position u need to move this part of your code inside the switch-case. You have to be careful with images inside your ListView, more info about that here:
http://developer.android.com/training/improving-layouts/smooth-scrolling.html
Now i can create PagerIndicator but i don't know how to put map it, which one page will show Driving Stat. and another one will show map+driving stat. In addition, Is it possible to make 2 view work together as you see in the picture below.(the time and distance still run)
I don't know about GMap control but here is how I use different layouts in my app.
First you could create a layout for your Map control
Secondly add it in your ViewPager
#Override
public Object instantiateItem(View pager, int position) {
LayoutInflater inflater = (LayoutInflater) SettingsActivity.this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = null;
switch (position) {
case 0: //first page
view = inflater.inflate(R.layout.yourMapLayout,
null);
TextView text = (TextView) view
.findViewById(R.id.text);
text.setText("I am an added text")
...
If I understood corect and you are using android.support.v4.view.ViewPager , which would be a good candidate to accomplish your task.
I use below code and it works :)
#Override
public Object instantiateItem( View pager, final int position )
{
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = null;
if(position == 0) {
view = inflater.inflate(R.layout.my_map, null);
((ViewPager) pager).addView(view,0);
}
return view;
}
I have a ListView, and I have added a header (with getListView().addHeaderView) that simply contains a TextEdit widget.
Then when I tap the TextEdit to start writting, the keyboard appears and it messes up the list!
If I tap everywhere else to hide the keyboard, the list messes up again!
I don't know why is this happening. I thought it was something related with the onConfigurationChanged method, but after implementing it (and adding the corresponding attribute in the manifest file) the problem persists.
How could I fix it? Why is Android messing up my list?
EDIT:
My list uses a custom adapter, this is the getView method:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v != null) {
return v;
}
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.list_row, null);
ListTask list_item = items.get(position);
if (list_item != null) {
TextView item_name = (TextView) v.findViewById(R.id.item_name);
item_name.setText(list_item.getTitle());
}
return v;
}
The problem is not the value of my items, but their order. They are displayed in a different order when the keyboard appears, but the values are correct.
EDIT2:
Ok, I have changed my getView method with rekaszeru's suggestion and now it works as expected. But now I'm facing another problem: what if my items have two textviews?
Let's say the second textview is optional, and "Item 1" and "Item 3" have it, but "Item 2" does not, so it's initialized as a void String (length == 0).
The first time the list is displayed, it shows "Item1" and "Item 3" with their second textview, and "Item 2" without it. That's correct. But when the keyboard appears, the "Item 2" takes the second textview of another item and displays it!
This is the modified code I have right now:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater vi = (LayoutInflater) getContext().
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.list_row, null);
}
ListTask list_item = items.get(position);
TextView item_name = (TextView) convertView.findViewById(R.id.item_name);
TextView item_optional_text = (TextView) convertView.findViewById(R.id.item_optional_text);
item_name.setText(list_item.getTitle());
// if the item has defined the optional text, make some room and display it
if (item_optional_text.isNotEmpty()) {
LayoutParams layout_params = (LayoutParams) item_name.getLayoutParams();
layout_params.topMargin = 10;
layout_params.height = -2; // -2: wrap_content
item_name.setLayoutParams(layout_params);
item_optional_text.setText(list_item.getOptionalText());
}
return convertView;
}
The isNotEmpty() does this in the Item class:
public boolean isNotEmpty() {
return this.optional_text.length() > 0;
}
Maybe it's too complex to understand in a written question. If so, I can make a short video showing the problem and my source code. Thanks in advance for your help guys.
Your row recycling is messed up. Android is not changing the order of the items, you are.
Right now, if you are passed a row to recycle, you return it without modification. This is a mistake. You are supposed to modify the contents of the row to reflect the data at the supplied position. The only piece of logic you can skip in this case is inflating a brand-new row.
Here is a free excerpt from one of my books that goes through all of this.
You should override the getView method in your ListAdapter implementation, and make sure that you always assign a new value to the view that you are returning (or at least always update it to contain the proper data).
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
convertView = inflater.inflate(R.layout.list_row, parent, false);
//set the necessary data in your TextViews, Checkboxes, etc...
return convertView;
}
If you don't inflate your item renderer, then you can instantiate it from code, like:
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
convertView = new TextView([...]);
convertView.setText(textBasedOnYourData);
return convertView;
}
Edit
As #CommonsWare noted, attention should be payed to the recycling of your list item renderer. So instead of instantiating it every time, you should check whether it already exists or not, and update the underlying TextView afterwards.
So I'd suggest give a try to this slightly modified getView implementation:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater vi = (LayoutInflater) getContext().
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.list_row, null);
}
ListTask list_item = items.get(position);
TextView item_name = (TextView) convertView.findViewById(R.id.item_name);
//the item should never be null, but just in case:
item_name.setText((list_item == null) ? "" : list_item.getTitle());
return convertView;
}
I have a ListView on my ListActivity and I'd like the rows of the ListView to be 1 of 3 different layouts. The first item in my list is always going to use layout A, the second item in my list is always going to use layout B, and all subsequent items are going to use layout C.
Here is my getView function:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// get the View for this list item
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
switch (position) {
case 0:
v = vi.inflate(R.layout.layout_A, parent, false);
break;
case 1:
v = vi.inflate(R.layout.layout_B, parent, false);
break;
default:
v = vi.inflate(R.layout.layout_C, parent, false);
break;
}
}
switch (position) {
case 0:
TextView txtLabel1 = (TextView)findViewById(R.id.label1);
TextView txtLabel2 = (TextView)findViewById(R.id.label2);
if (txtLabel1 != null) {
txtLabel1.setText("sdfasd");
}
if (txtLabel2 != null) {
txtLabel2.setText("dasgfadsasd");
}
break;
default:
break;
}
// return the created view
return v;
}
R.id.label1 and R.id.label2 are TextViews on R.layout.layout_A. However, txtLabel1 and txtLabel2 are null after trying to set them. Why?
I stepped through this code in the debugger and it inflated the correct layout (R.layout.layout_A) and fell into the correct case below to set the R.id.label1 and R.id.label2 text.
Also, if there is a better way to do this, please let me know.
Looks like "View v = convertView; if (v == null) {..." is a problem. You should re-create view every time because you don't know the type of given view. Also, you can use viewholder approach for more efficient implementation. You can find some ideas in this blog: http://codinglines.frankiv.me/post/18486197303/android-multiple-layouts-in-dynamically-loading