It has been a long time since I did some Android and now I want to get back to it. I still try to grasp the concept of using Fragments properly and what would be the proper way to do what I need to.
To the point. I need to have a Main view that (for now) contains one card. This card will contain a TextView and a ListView with custom items(one image and two rows of text). How would I implement this?
Do I need to do a different fragment for the listView and another for the card? I know I need a custom Adapter for the list view but how do I go on putting everything together?
Any advice is welcomed, even in the most basic diagram form.
fragment_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
tools:context=".MainActivity$PlaceholderFragment"
android:paddingLeft="5dp"
android:paddingTop="10dp"
android:paddingRight="5dp"
android:paddingBottom="10dp">
<android.support.v7.widget.CardView
android:id="#+id/accounts_card"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_gravity="top"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="150dp"
android:layout_marginLeft="5dp"
card_view:cardCornerRadius="0dp"
card_view:cardBackgroundColor="#color/white"
card_view:cardElevation="3dp"
android:layout_marginRight="5dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="5dp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/accounts_title"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="#style/Base.TextAppearance.AppCompat.Caption"
android:elevation="1dp"
android:text="My Accounts"
android:gravity="top|center"
android:textStyle="bold"
android:textSize="20dp"
android:paddingTop="15dp"
android:paddingBottom="15dp" />
<ListView
android:id="#+id/accounts_list"
android:layout_below="#id/accounts_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
my_listitem.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/account_item">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/b_logo"
android:elevation="1dp"/>
<LinearLayout
android:layout_alignEnd="#id/b_logo"
android:paddingLeft="2dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="right">
<TextView
android:id="#+id/account_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="9959593922923"/>
<TextView
android:id="#+id/account_code"
android:layout_below="#id/account_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="30-15-55"/>
</LinearLayout>
</RelativeLayout>
First of all, if you want to have different navigatable cards containing text and list views, I would recommend using a PageAdapter , in which each card can be loaded to the adapter in the beginning of the Activity like this:
public class CustomAdapter extends PagerAdapter {
#Override
public Object instantiateItem(ViewGroup collection, int position) {
mContext=collection.getContext();
LayoutInflater inflator=(LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view=inflator.inflate(R.layout.fragment_main, null);
//do things to initiate the card like loading a text by accessing the text through TextView tv=(TextView)view.findElementsById(R.id.accounts_title);
return view;
}
And for the List in your card, create a New subclass of Base Adapter Class and instantiate the layout my_listitem.xml there and return the view for each item in list , this can be done like this:
public class CustomListAdapter extends BaseAdapter {
private static List<?> list;
#Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
RelativeLayout layout = null;
salahLayout=(RelativeLayout) LayoutInflater.from(mContext).inflate(R.layout.my_listitem, null);
notifyDataSetChanged();// to notify the list has been changed
return layout;
}
}
You may need to set the List in the CustomListAdapter Class using some setter method and then in the getView method you can create the view for each item in the list Item using the list.
To use the CustomListAdapter as the adapter for your list in the card in CustomAdapter class add this:
ListView list=(ListView)view.findElementById(R.id.accounts_list);
list.setAdapter(mCustomListAdapter);//set the object of the customlistadapter class
Fragments are used for changing part of Main UI .Refer the Below link:http://developer.android.com/guide/components/fragments.html
Related
This question already has answers here:
RecyclerView items with big empty space after 23.2.0
(5 answers)
Closed 3 months ago.
I'm making a ToDo list app, and while testing it, for some reason, a huge gap forms between the items whenever I try to scroll down. It always happens whenever I Drag and Drop the items, but I don't see any errors with my ItemTouchHelper adapter and callback class. It would be awesome if you can help me out.
Before:
After:
RecyclerAdapter.java
public class RecyclerAdapter extends
RecyclerView.Adapter<RecyclerAdapter.RecyclerVH> implements ItemTouchHelperAdapter{
private LayoutInflater layoutInflater;
ArrayList<Info> data;
Context context;
public RecyclerAdapter(Context context) {
layoutInflater = LayoutInflater.from(context);
this.context = context;
}
public void setData(ArrayList<Info> data) {
this.data = data;
notifyDataSetChanged();
}
#Override
public RecyclerVH onCreateViewHolder(ViewGroup viewGroup, int position) {
View view = layoutInflater.inflate(R.layout.custom_row, viewGroup, false);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("R.A onClick Owen", "onClick method triggered");
}
});
RecyclerVH recyclerVH = new RecyclerVH(view);
return recyclerVH;
}
#Override
public void onBindViewHolder(RecyclerVH recyclerVH, int position) {
Log.d("RecyclerView", "onBindVH called: " + position);
final Info currentObject = data.get(position);
// Current Info object retrieved for current RecyclerView item - USED FOR DELETE
recyclerVH.listTitle.setText(currentObject.title);
recyclerVH.listContent.setText(currentObject.content);
/*recyclerVH.listTitle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Open new Activity containing note content
Toast.makeText(this, "Opening: " + currentObject.title, Toast.LENGTH_LONG).show();
}
});*/
}
public void deleteItem(int position) {
DBInfo dbInfo = new DBInfo(context);
dbInfo.deleteNote(data.get(position));
// Deletes RV item/position's Info object
data.remove(position);
// Removes Info object at specified position
notifyItemRemoved(position);
// Notifies the RV that item has been removed
}
#Override
public int getItemCount() {
return data.size();
}
// This is where the Swipe and Drag-And-Drog methods come into place
#Override
public boolean onItemMove(int fromPosition, int toPosition) {
// Swapping positions
// ATTEMPT TO UNDERSTAND WHAT IS GOING ON HERE
Collections.swap(data, fromPosition, toPosition);
notifyItemMoved(fromPosition, toPosition);
return true;
}
#Override
public void onItemDismiss(int position) {
// Deleting item from RV and DB
deleteItem(position);
}
class RecyclerVH extends RecyclerView.ViewHolder implements View.OnClickListener{
// OnClickListener is implemented here
// Can also be added at onBindViewHolder above
TextView listTitle, listContent;
public RecyclerVH(View itemView) {
super(itemView);
listTitle = (TextView) itemView.findViewById(R.id.title);
listContent = (TextView) itemView.findViewById(R.id.content);
listTitle.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Toast.makeText(context, "Opening: Note" + getLayoutPosition(), Toast.LENGTH_SHORT).show();
// PS NEVER ADD listTitle VARIABLE AS PUBLIC VARIABLE ABOVE WHICH IS GIVEN VALUE AT ONBINDVH
// THIS IS BECAUSE THE VALUE WILL CHANGE IF ITEM IS ADDED OR DELETED
}
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fab="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical"
android:weightSum="1">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/rounded_corners" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerList"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.melnykov.fab.FloatingActionButton
android:id="#+id/fab_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp"
android:layout_marginEnd="16dp"
android:gravity="bottom|end"
android:onClick="addNote"
android:src="#drawable/fab_ic_add"
fab:fab_colorNormal="#color/colorPrimary"
fab:fab_colorPressed="#color/colorPrimaryDark"
fab:fab_colorRipple="#color/colorPrimaryDark" />
</RelativeLayout>
</FrameLayout>
</LinearLayout>
custom_row.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/main"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="8dp"
android:text="#string/test"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/main"
android:paddingLeft="8dp">
<TextView
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/test"
android:textSize="15sp" />
</LinearLayout>
</RelativeLayout>
Thank you so much to whoever can help me out. I am pulling my hair out as I type.
EDIT: I have confirmed that it is not my ItemTouchHelper class that's the problem. (Tried running without it being called, problem still occurs.)
Also, it seems that when a dialog is shown and the keyboard brought up, the RecyclerView in the background resolves the problem by itself. After dialog is removed, the problem repeats (i.e. Scrolling puts massive space between items)
change in Recycler view match_parent to wrap_content:
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
Also change in item layout xml
Make parent layout height match_parent to wrap_content
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
This happened to me many times!
All you need to do is... make layout_height of row file wrap_content and your problem solved..
android:layout_height="wrap_content"
Happy coding!
Its because you are using match_parent in height of root view of the row item in your vertically oriented listview/recyclerview. When you use that the item expands completely wrt to its parent.
Use wrap_content for height when the recyclerview is vertically oriented and for width when it is horizantally oriented.
Avoid taking the view in item layout with a container like this:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data/>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:listPreferredItemHeight"
android:textAppearance="?android:attr/textAppearanceMedium" />
</android.support.constraint.ConstraintLayout>
</layout>
as in this case match_parent will do its work and the problem will still remain! Rather take it like this:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data/>
<TextView
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:listPreferredItemHeight"
android:textAppearance="?android:attr/textAppearanceMedium" />
</layout>
[Note: Above code has data binding attached to it, don't use <layout> & <data> tags if not using data binding]
Other than this, if you must use any view group containers, than take a look the height and width attributes in the container, and try change those from match_parent to wrap_content. That should resolve the issue. For more transparency, one can try giving background colours and see through it to identify actual problem.
Just for the record: Since in my case we had to implement some "superfancy UI" with overlapping RecyclerView and blur effect toolbar, I had to get rid of clipToPadding="false" within RecyclerView-xml.
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/height_toolbar"
android:paddingBottom="#dimen/height_bottom_bar_container"
//android:clipToPadding="false" <-- remove this flag!
android:scrollbars="vertical"
/>
paddingTopand paddingBottom worked, but we replaced it with some GapViews(empty views, with height of paddingTop and paddingBottom)
if someone is using | recyclerViewObject.setHasFixedSize(true);
try removing it, It was causing the issue in my case.
You can try setting your Viewgroup holding the recyclerview to wrap content
i have this problem and i just use
android:layout_height="wrap_content"
for parent of every item.
i a have a specific design in my photoshop, but i cant figure out how to make it in android for a table row. As you can see bellow in the picture, i need a list of alarms. So i was thinking to make it as table row for every row same so i can input stuff to that table row via *.java.
Heres picture
and here is my code what i have now
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#162030"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="#+id/textView1"
android:layout_marginTop="76dp"
android:background="#131b29"
>
<TableLayout
android:layout_width="fill_parent"
android:layout_height="774dp"
android:orientation="vertical" >
<TableRow
android:id="#+id/TableRow04"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="0dp"
android:background="#162030"
android:minHeight="60dp" >
</TableRow>
<TableRow
android:id="#+id/TableRow05"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="0dp"
android:background="#162030"
android:minHeight="60dp" >
</TableRow>
</TableLayout>
</ScrollView>
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="76dp"
android:shadowColor="#62f1fa"
android:shadowDx="0.0"
android:shadowDy="0.0"
android:shadowRadius="20"
android:text="0:00"
android:textColor="#5ee6ef"
android:textSize="50sp" />
Make your main xml layout as this :
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" ... >
<ListView
android:id="#+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" ... />
Create a layout for your custom styled item list (alarm_item.xml in layout folder) :
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- This is your clock icon -->
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<!-- This is your alarm clock name -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<!-- Create imageview and textview for all other needed data -->
</RelativeLayout >
Create an adapter to fill listview with item (take a look there for more details) :
public class AlarmAdapter extends BaseAdapter {
Context context;
Arraylist data;
private static LayoutInflater inflater = null;
public yourAdapter(Context context, Arraylist data) {
// TODO Auto-generated constructor stub
this.context = context;
this.data = data;
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get object from list that contains Alarm data for this view
// I assume that your alarm data correspond to an object name AlarmData
AlarmData alarmData = getItem(position)
View rootView = convertView;
if (rootView == null)
rootView = inflater.inflate(R.layout.alarm_item, parent, false);
TextView alarmClockName= (TextView) rootView.findViewById(R.id.alarm_clock_name);
ImageView clockIcon = (ImageView ) rootView.findViewById(R.id.alarm_clock_name);
// Set your data there
clockIcon.setImageResource(iconRes);
alarmClockName.setText(alarmData.getName());
return rootView;
}
}
Finally get and fill listview with items in MainActivity :
public class AlarmActivity extends Activity {
// I assume that your alarm data correspond to an object name AlarmData
// so I define a Arraylist that will contains all alarms to display
ArrayList<AlarmData> alarmList = new ArrayList<Alarmdata>();
ListView listview;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Get listivew from main layout
listview = (ListView) findViewById(R.id.listview);
// Add alarm to display in alarmlist
alarmList.add(new AlarmData());
alarmList.add(new AlarmData());
// Create alarm listview adapter with current context (this) and alarmlist
AlarmAdapter alarmAdapter = new AlarmAdapter(this, alarmList);
// Set previous adapter on listview
listview.setAdapter(alarmAdapter);
}
}
This is just a simple example of Custom listview adapter, hope this helps you.
After creating this mecanisme you just have to work on your item layout
I have a Fragment, and I want to have a ViewPager inside of it, but only want part of the page to be a ViewPager, so I'm not making the ViewPager the contentView of the Activity. I'm having a couple problems: I don't know where to "fill in" my view, and I don't know what to do in destoryItem.
Here's what I have (I'm probably missing stuff):
In my Fragment, I am getting the entire fragment layout, and then the ViewPager item from within it, setting the Adapter, the id (not sure if this is needed or what it does), and setting the currentItem.
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_how_to_play, parent, false);
HowToPlayPagerAdapter adapter = new HowToPlayPagerAdapter(getActivity());
ViewPager viewPager = (ViewPager) v.findViewById(R.id.how_to_play_view_pager);
viewPager.setAdapter(adapter);
viewPager.setId(R.id.viewPager);
viewPager.setCurrentItem(0);
return v;
}
Still in this Class I have my PagerAdapter, this is where I know there are problems as I am not sure how exactly to implement this.
class HowToPlayPagerAdapter extends PagerAdapter {
private Activity parent;
public HowToPlayPagerAdapter(Activity parent) {
this.parent = parent;
}
public Object instantiateItem(View collection, int position) {
// TODO: In here I think we'll want to really get the same view every time and just fill it in properly
return parent.findViewById(R.id.how_to_play_view_pager_id);
}
#Override
public int getCount() {
return mHowToPlayPages.size();
}
#Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == ((View) arg1);
}
#Override
public void destroyItem(View container, int position, Object object) {
super.destroyItem(container, position, object);// No idea what to do in here
}
}
This is my fragment layout where the ViewPager is actually defined.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/top_header_background_shadowed"
android:orientation="horizontal"
android:paddingBottom="8dp"
android:paddingLeft="16dp"
android:paddingTop="8dp" >
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:src="#drawable/ic_launcher" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:src="#drawable/logo_need2buythis" />
</LinearLayout>
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="#+id/how_to_play_view_pager" />
</LinearLayout>
And this is the layout for the View I'd like to be inside the ViewPager and then I would fill in the TextView and other elements I'm yet to add depending on which position we're at in the Pager.
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:id="#+id/how_to_play_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="32dp"
android:text="Gameplay" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
</ScrollView>
Currently when I run it I do see the fragment layout but I see nothing where the ViewPager content should be (no surprise there because I'm not filling in anything with the Text in my current implementation because I don't know where/how to), and when I start just swiping back and forth for a while my app eventually crashes saying I did not override destroyItem.
I know that there has been simialr questions but I can't make it work even though I look at those. The error message is:
java.lang.RuntimeException: Your content must have a ListView whose id
attribute is 'android.R.id.list'
. I have tried to change the id to list. In another. This what the code looks like:
public class committeeFragment extends SherlockListFragment {
private CommitteeAdapter adapter;
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
adapter = new CommitteeAdapter(getActivity().getApplicationContext());
setListAdapter(adapter);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
return inflater.inflate(R.layout.fragment_committee, container, false);
}
public void
refreshList() {
adapter.updateDataSet();
adapter.notifyDataSetChanged();
}
}
It's using the following adapter:
public class CommitteeAdapter extends BaseAdapter {
private
ArrayList<StudentCommittee> committeeList;
private Context context;
public CommitteeAdapter(Context context) {
this.context = context;
CommitteeDatabaseAdapter dbAdapter = new CommitteeDatabaseAdapter(context);
committeeList = dbAdapter.readAllCommittees();
}
public void updateDataSet() {
CommitteeDatabaseAdapter dbAdapter = new CommitteeDatabaseAdapter(context);
committeeList = dbAdapter.readAllCommittees();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
StudentCommittee committee = committeeList.get(position);
View v = vi.inflate(R.layout.list_item_committee, null);
TextView sectionName = (TextView) v.findViewById(R.id.committee_namn);
sectionName.setText(committee.getName());
return v;
}
#Override
public int getCount() {
return committeeList.size();
}
#Override
public StudentCommittee getItem(int position) {
return committeeList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
}
Here is the xml-file that specifies the list(fragment_committee):
<?xml version="1.0" encoding="utf-8"?> <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:tag="#string/tag_fragment_committee"
android:background="#color/white" >
<TextView
style="#style/AppsolutText.Headline"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Festerier" />
<View
android:layout_width="fill_parent"
android:layout_height="2dp"
android:background="#drawable/divider_sliding_menu_item"/>
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
style="#style/AppsolutText.Normal"
android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Uppdatera för att se en lista över festerier och fadderier. Kräver internetanslutning."/>
</LinearLayout>
Here is the xml for the list item:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ImageView
android:id="#+id/committee_symbol"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:paddingBottom="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp" />
<TextView
android:id="#+id/committee_namn"
style="#style/AppsolutText.ListHeader"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
I hope that you can figure out what's wrong. I have another listview that has the same id (list) in another xml-file within the project. I don't know if that's a problem. Please help me solve the problem.
The problem is here :
android:id="#+id/list"
you are adding a new id for your ListView but ListFragment needs a default Android ListView Id
change your ListView Id to :
<ListView
android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Change your ListView in XML to have the following id:
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
It's a requirement of using ListFragment/SherlockListFragment
http://developer.android.com/reference/android/app/ListFragment.html
ListFragment has a default layout that consists of a single list view. However, if you desire, you can customize the fragment layout by returning your own view hierarchy from onCreateView(LayoutInflater, ViewGroup, Bundle). To do this, your view hierarchy must contain a ListView object with the id "#android:id/list" (or list if it's in code)
You can try to clean your project. If any xml releted error have , you can find it. Then you can change your list id . Find the list id are exist into your gen folder R.java class.
I decided to stop using actionbarsherlock and use the support libraries instead to get action bar in Android 2.1 and above. After doing this, i got the "java.lang.RuntimeException: Your content must have a ListView whose id attribute is 'android.R.id.list'". What i did to remedy this problem was
to read this http://developer.android.com/reference/android/app/ListFragment.html#q=fragment
then change my fragment layout file from
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/item_detail"
style="?android:attr/textAppearanceLarge"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:textIsSelectable="true"
tools:context=".ItemDetailFragment" />
to
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="8dp"
android:paddingRight="8dp"
tools:context=".ItemDetailFragment">
<ListView android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00FF00"
android:layout_weight="1"
android:drawSelectorOnTop="false"/>
<TextView android:id="#+id/item_detail"
style="?android:attr/textAppearanceLarge"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:textIsSelectable="true"/>
<TextView android:id="#id/android:empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF0000"
android:text="No data"/>
... and voila, the RunTimeException with missing android.R.id.list was gone! Of course, i need to edit my new layout and fix it properly, but the key issue here was that i had overridden the fragment layout in its onCreateView method. ActionBarSherlock DID NOT have a problem with this, but with the Android support library, if u do this, you MUST have a ListView in your XML Layout, with the android:id="#id/android:list" as stated in the info linked to above.
Hope this helps (coming from a total newb in Android app dev)!
i am working on an Android app that needs showing a list[table], inside the layout[view]
I come from iPhone dev objC land, and i have an app that shows a table[list] inside the view[layout]
So how to show a list inside my layout, and place it to specified location [center],
ps. I havent found a list in the graphical layout editor of the xml, where is the list[table]?
2. I have done some tests with list views, but is a view, that replace the xml view, i want it inside my xml,,
thanks a lot!
Yes, of course, you can do that
1) you need to have listholder.xml here, you can scratch anything in you layout view, either imageview, textview..etc. just don't forget to add ListView inside it. for example:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/head_logo_bg">
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/background_label">
<TextView
android:id="#+id/city_txt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_gravity="center"
android:text="Sydney"
android:textStyle="bold"
android:textSize="17sp"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="40sp">
<ListView
android:id="#android:id/list"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_centerVertical="true"
android:scrollingCache="false"/>
</LinearLayout>
2) For custom your own list item, you have to create listitem.xml i.e.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/listitemone"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10sp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="vertical">
<ImageView android:id="#+id/user_image"
android:layout_width="80px" android:layout_height="80px"
android:layout_alignParentLeft="true"
android:layout_marginRight="5px"
android:src="#drawable/icon"
/>
</LinearLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="5sp"
android:orientation="vertical">
<TextView
android:id="#+id/date_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/date"
android:textStyle="bold"
android:textSize="16sp" />
<TextView
android:id="#+id/date_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignBaseline="#id/date_label"
android:layout_marginRight="20sp"
android:textColor="#FFF"
android:text="MM/dd/YYYY"
android:textStyle="bold"
android:textSize="16sp" />
</RelativeLayout>
</LinerLayout>
3) create customAdapter in your activity, it would look like this;
public class MyListActivity extends ListActivity {
private ArrayList<Yourdata> yourdata = new ArrayList<Youdata>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listholder);
// yourdata might be array, arraylist etc.
MyCustomAdapter listadapter = new MyCustomAdapter(this, R.layout.listitem, yourdata);
setListAdapter(listadapter);
}
private class MyCustomAdapter extends ArrayAdapter<Yourdata>{
//this case, i use Yourdata as type
private ArrayList<Yourdata> items;
public PreviousAdapter(Context context, int textViewResourceId,
ArrayList<Yourdata> items) {
super(context, textViewResourceId, items);
this.items = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if(v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.listitem, null);
}
Yourdata yt = items.get(position);
if(yt != null){
// Don't forget to use v.findView...., otherwise, it might force close when run app.
TextView dateStr = (TextView)v.findViewById(R.id.date_value);
dateStr.setText(yt.getDate());
}
return v;
}
}
}
P.S. the above code might not exactly right... just give you an idea :)
Here is a source about custom list (you might have seen it) hope it useful
http://www.vogella.de/articles/AndroidListView/article.html
I have try these example it's very nice.
you can get the example from
http://www.codeproject.com/Articles/507651/Customized-Android-ListView-with-Image-and-Text?msg=4567162#xx4567162xx