I am developing an android application which contains a ListAtivity class and get it is data as follow :
ArrayAdapter<Item> ara=new MyArrayAdapter(this,_items);
setListAdapter(ara);
And I defined MyArrayAdapter :
....
public MyArrayAdapter(Activity context, List<BirthdayContact> list) {
super(context,R.layout.list_row,0,list);
//super(context, R.layout.birthday_list, list);
this.context = context;
this.list = list;
}
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
LayoutInflater inflator = context.getLayoutInflater();
view = inflator.inflate(R.layout.birthday_list_row, null);
final ViewHolder viewHolder = new ViewHolder();
viewHolder._cName= (TextView) view.findViewById(R.id.contact_name);
viewHolder._cImage = (ImageView) view.findViewById(R.id.contact_image);
viewHolder._cbirthDay=(TextView)view.findViewById(R.id.contact_birthday_remained);
view.setTag(viewHolder);
}
......
But the problem with this way is that you cant only assign each row`s template and you cant have other widget on list view which are not part of list of data. I mean I want to have a say a TextView which shows messages to user, and below that I show the list of rows.
Can you help me please?
If you want a different layout than a simple ListView you have the option of setting the content view to a layout file like this:
setContentView(R.layout.layout_with_diferrent_views); // call this on the onCreate() method
where R.layout.layout_with_different_views could be a xml layout like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
Because you extends ListActivity you must have in the layout a ListView element with the id #android:id/list. Of course you can have a more complex layout than the one above as long as you have a ListView element with the id #android:id/list
You should consider using a listHeader : lv.addHeaderView(findViewById(R.id.header));
This has to be done in your onCreate method in your activity, and you must provide a widget with the id header.
If you want other components in activity.Then better consider Normal Activity instead ListActivity.
Related
In a fragment, I have a ListView that has a custom ParseQueryAdapter<T>. The problem may not have anything to do with Parse, although I'm not sure.
As I was testing my app, I noticed something very strange. When I would scroll down my ListView, all the visible ListView items would be drawn on top of the next ListView item as seen in the second image below.
The list initialized properly as such:
As you can see, in my list item layout, I have an ImageView (ParseImageView to be specific) and a TextView. The TextView now displays some notes (don't mind the ID user_name_text_view) and the ImageView displays a placeholder blank profile picture.
When I scrolled down, the list looked like:
Here's my list view layout named fragment_post_view_list_view:
<?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" >
<ListView
android:id="#+id/post_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
Here's my list item layout named list_item_post_view:
<?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="wrap_content">
<com.parse.ParseImageView
android:id="#+id/icon"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_alignParentLeft="true"
android:background="#drawable/com_facebook_profile_picture_blank_square" />
<TextView
android:id="#+id/user_name_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/icon"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/link_blue" />
</RelativeLayout>
Here's my adapter named PostViewListViewAdapter:
public class PostViewListViewAdapter extends ParseQueryAdapter<Post> {
// call superclass with a query to populate list view
public PostViewListViewAdapter(Context context, final String[] postsObjectIds) {
super(context, new ParseQueryAdapter.QueryFactory<Post>(){
public ParseQuery<Post> create() {
ParseQuery<Post> query = Post.getQuery();
query.whereContainedIn("objectId", Arrays.asList(postsObjectIds));
return query;
}
});
}
// this is similar to getView method in an adapter
#Override
public View getItemView(Post post, View v, ViewGroup parent) {
if(v == null) {
v = View.inflate(getContext(), R.layout.list_item_post_view, null);
}
super.getItemView(post, v, parent);
TextView usernameTextView = (TextView) v.findViewById(R.id.user_name_text_view);
usernameTextView.setText(post.getNotes()); // some string
return v;
}
}
How can I fix this problem?
Is this an issue with XML or Java?
I was following the two tutorials from Parse and the example from the Parse docs:
MealSpotting
Parse Query Adapter
I set the adapter and ListView here:
View rootView = inflater.inflate(R.layout.fragment_post_view_list_view, container, false);
mPostsObjectIds = SOME_STRING[];
PostViewListViewAdapter adapter = new PostViewListViewAdapter(getActivity(), mPostsObjectIds);
ListView listView = (ListView) rootView.findViewById(R.id.post_list_view);
listView.setAdapter(adapter);
I've tried getting rid of the ParseImageView in my list item layout, but my TextViews still draw on top of each other when I scroll.
Edit:
I forgot to mention that the list items display on top of each other after an orientation change.
I tested this on my Galaxy S5 (Android version 4.4.2 and Parse 1.4.1).
In my Activity, I show the Fragment here (called PostViewListViewFragment):
getSupportFragmentManager().beginTransaction().add(android.R.id.content, new PostViewListViewFragment()).commit();
Try below layout :
<?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"
android:orientation="vertical" >
<ListView
android:id="#+id/post_list_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars="none" >
</ListView>
</RelativeLayout >
Make Sure your adapter like this:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
// reuse views
if (rowView == null) {
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(R.layout.rowlayout, null);
// configure view holder
ViewHolder viewHolder = new ViewHolder();
viewHolder.text = (TextView) rowView.findViewById(R.id.TextView01);
rowView.setTag(viewHolder);
}
// fill data
ViewHolder holder = (ViewHolder) rowView.getTag();
String s = names[position];
holder.text.setText(s);
return rowView;
}
}
PS:You should watch this Google IO video about Listview,and here is the slides.
First create a ViewHolder class
static class ViewHolder {
protected TextView usernameTextView;
}
Then change your getItemView method like below
public View getItemView (Post post, View convertView , ViewGroup parent)
{
ViewHolder viewHolder = null;
if (convertView == null)
{
LayoutInflater inflator = context.getLayoutInflater();
convertView = inflator.inflate(R.layout.list_item_post_view, null);
viewHolder = new ViewHolder();
viewHolder.usernameTextView = (TextView)convertView.findViewById(R.id.user_name_text_view);
convertView.setTag(viewHolder);
convertView.setTag(R.id.user_name_text_view, viewHolder.usernameTextView);
}
else
{
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.usernameTextView.setText(post.getNotes()); // some string
return convertView;
}
The problem seems to be in your list item layout -
Change it to this -
<?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="wrap_content">
<com.parse.ParseImageView
android:id="#+id/icon"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_alignParentLeft="true" />
<TextView
android:id="#+id/user_name_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/icon"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/link_blue" />
</RelativeLayout>
Probably you have extra background for each list item set that is causing such effect.
Alter and watch.
Hope this gives you idea!
Try changing your list view layout height to match_parent.
Credit to #VedPrakash for helping me fix this.
In case it helps anyone, I fixed the problem by replacing the fragment not adding it. So I changed this line from:
getSupportFragmentManager().beginTransaction().add(android.R.id.content, new PostViewListViewFragment()).commit();
to:
getSupportFragmentManager().beginTransaction().replace(android.R.id.content, new PostViewListViewFragment()).commit();
I connent an addevent.java with addevent.xml is content a listview, the listview take its element from another XML file "item.xml"
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="#+id/d"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:drawablePadding="0dip"
android:drawableRight="#drawable/icon_name" />
<EditText
android:id="#+id/en"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toLeftOf="#+id/d" >
</EditText>
</LinearLayout>
now I need to findviewbyId not from basic xml file but form another "item.xml"
I tried LayoutInflater as this, code but it isn't work:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.addevent);
myList = (ListView) findViewById(R.id.MyList);
myList.setItemsCanFocus(true);
myAdapter = new MyAdapter();
myList.setAdapter(myAdapter);
final LayoutInflater factory = getLayoutInflater();
final View textEntryView = factory.inflate(R.layout.item, null);
tvDisplayDate = (EditText)textEntryView.findViewById(R.id.editd);
btnChangeDate=(Button)textEntryView.findViewById(R.id.d);
any help please
Try this View view = LayoutInflater.from(getApplication()).inflate(R.layout.item, null);
How you can see, static from() method takes 1 argument(Context) and you obtains LayoutInflater from given Context, in your case it will be your Activity where you want to inflate View.
Hope it helps!
From insinde your MyAdapter class you can override the getView method (that's the one that produces the item renderers on demand).
After recycling / inflating the proper layout for the current item (say convertView), you can access all of its children using the findViewById method called on the convertView:
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
// initialize, inflate convertView from your layout if needed;
tvDisplayDate = (EditText)convertView.findViewById(R.id.editd);
// populate convertView with the item's details
}
I have a ListView (with an Adapter of my own) where I'd like to add a delete button by swaping an item on the ListView (like on iPhones).
I really don't know how to do it and where to start ...
Could you please give me some hints ?
Thanks
What you want to implement is a custom ListView. You need a layout for your row, here's an example
res/layout/row.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#android:color/transparent">
<TextView android:id="#+id/Browse_DateTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent" />
<ImageButton android:id="#+id/delete"
android:layout_width="wrap_content"
android:layout_height="fill_parent" />
</LinearLayout>
Then you need to overide the getView() method of your adapter, a little like this:
setListAdapter(new ArrayAdapter<Object>(this, R.layout.row, R.id.Browse_DateTime, ourRows) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)BrowseActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.row, null);
}
TextView time = (TextView) v.findViewById (R.id.Browse_DateTime);
time.setText(ourRows[position].dateTime);
ImageButton delete = (ImageButton) v.findViewById(R.id.delete);
delete.setFocusable(false);
delete.setImageDrawable(BrowseActivity.this.getResources().getDrawable(R.drawable.deletebutton));
delete.setOnClickListener(BrowseActivity.this);
delete.setId(position);
return v;
}
};)
Best regards.
PS: this is cut&paste from my code, BrowseActivity is just the name of the activity this code resides in, R.layout.row is my row.xml file, you name it any which way, just put it in /res/layout/, and if your delete button is an imagebutton, you DO need the delete.setFocusable(false); (try it without and see why).
I am a new android developer . I have create a quiz application where i need to display the questions in list view serially . my all question and options are images. how can i set the images in list view. i want to set only the image in list view not any text . Please help me.
Create a listview in your main xml file like this:
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/masterLayout"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ListView
android:id="#+id/list"
android:cacheColorHint="#00000000"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Then create another xml file called child_layout:
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
Then in your activity class initialize your listview:
ListView listView1 = (ListView)findViewById(R.id.list);
Create a class that extends baseadapter and modify all the necessary methods the way you need to (create the constructor that takes a list of drawables as an argument and create a global variable that is set to the provided list). Then do the following in your activity class:
ArrayList<Drawable> images = new ArrayList<Drawable>();
// add to the list here
CustomListAdapter adapter = new CustomListAdapter(images);
listView1.setAdapter(adapter);
Do this in your getView() function in your customlistadapter class:
public View getView(int position, View convertView, ViewGroup parent)
{
Drawable image = images.get(position);
if (convertView == null)
{
LayoutInflater infalInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.child_layout, null);
}
ImageView imageView = (ImageView)convertView.findViewById(R.id.image);
imageView.setBackgroundDrawable(image);
return convertView;
}
ListView item click listener:
listView1.setOnItemClickListener(new ListView.OnItemClickListener()
{
public void onItemClick(AdapterView<?> listView, View itemView, int position, long itemId)
{
String message = "example text: " + position;
Toast.makeText(MyActivity.this, message, Toast.LENGTH_SHORT).show();
}
});
You need to create a Custom ListAdapter. An Example is give in API samples. Just add an ImageView as the layout of the custom adapter and you should get going. Search more for the examples.
take one main layout xml file in which you have to give the .
something like this
<List
android:width="wrap_content"
android:height="wrap_content"
android:id="#+id/list"
/>
and take another layout xml file with
<ImageView
android:width="wrap_content"
android:height="wrap_content"/>
In the adapter inflate this xml file that contains ImageView. so that you can get image in the list
look at this tutorial... and replace textview with image view and set images to it.
also have a look at this question...
Hope this helps.
Thanks.
Is there a site where I can find the inner workings of the BaseExpandableListAdapter? I read the API and I still don't understand how it loops through the whole array that is supplied to provide the view. I'm having problems with my own implementation. I can't create a whole list of expandable lists without using ExpandableListActivity, even though both are the same. It's supposed to retrieve strings from the database and create an expandablelistview out of each one, and add all the created expandablelists to a linearlayout inside main.xml. What happens is that only the expandablelistview for the first string is shown. Here's the snippet
Main Class:
public class MainActivity extends Activity implements OnClickListener {
DBAdapter groupTable = new DBAdapter(this);
ExpandableListView groupLabel;
GroupAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
groupTable.open();
adapter = new GroupAdapter(groupTable.getAllGroups());
retrieveExpandables(adapter);
groupTable.close();
Button addGroupButton = (Button)findViewById(R.id.addGroup);
addGroupButton.setOnClickListener(this);
}
public void retrieveExpandables(GroupAdapter adapter) {
LinearLayout layout = (LinearLayout)findViewById(R.id.grouplist);
LinearLayout groupLayout =
(LinearLayout)getLayoutInflater().inflate(R.layout.grouplistview, null);
ExpandableListView groupExpandableList =
(ExpandableListView)groupLayout.findViewById(R.id.groupLabel);
groupExpandableList.setAdapter(adapter);
layout.addView(groupLayout);
}
BaseExpandableListAdapter class:
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
if (convertView instanceof ViewGroup)
return (ViewGroup) convertView;
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
ViewGroup item = (ViewGroup)inflater.inflate(R.layout.grouplisttext, null);
TextView groupLabel = (TextView)item.findViewById(R.id.groupLabel);
groupLabel.setText(groups[groupPosition].name);
groupLabel.setVisibility(View.VISIBLE);
Log.d("A1", "This part repeating");
return item;
}
XML file for the TextView that will be the expandable list title
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:id="#+id/groups"
android:layout_height="wrap_content">
<TextView android:id="#+id/groupLabel"
android:textSize="24sp"
android:text="asdf"
android:textStyle="bold"
android:layout_width="fill_parent"
android:layout_weight="1"
android:layout_height="40dip"
android:layout_marginLeft="45dip"
android:gravity="center_vertical" />
</LinearLayout>
XML file for the ExpandableListView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:id="#+id/groups"
android:layout_height="wrap_content">
<ExpandableListView android:id="#+id/groupLabel"
android:textSize="24sp"
android:textStyle="bold"
android:layout_width="fill_parent"
android:layout_weight="1"
android:layout_height="40dip" />
</LinearLayout>
Sorry if I posted too much code, I tried removing as much unnecessary information as possible.
I found out where the problem went wrong. Apparently I got the LinearLayout and the ScrollView inside the main.xml interchanged, and the method for getViewGroup class was wrong. It's all good now