How to findViewById form another XML file? - android

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
}

Related

ListView with Custom Adapter [Android]

I'm trying to build a ListView with a custom layout but so far have not been able to successfully do it. I'm a beginner and have been following tutorials to get it done.
This is what I'm doing:
//this is where I want the custom list items to be displayed.
//GroupAdapter is the constructor of the class in which I'm trying to make a custom adapter
stringArray = new String[10];
groupItemArrayAdapter = new GroupAdapter(this,stringArray);
groupListView = (ListView) findViewById(R.id.mainList);
groupListView.setAdapter(groupItemArrayAdapter);
//this is the code in GroupAdapter.java class
public class GroupAdapter extends ArrayAdapter{
private LayoutInflater inflater;
public GroupAdapter(Activity activity, String[] items){
super(activity,R.layout.group_view);
inflater=activity.getWindow().getLayoutInflater();
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
return inflater.inflate(R.layout.group_view,parent,false);
}
}
When i start the app, a blank screen appears. Initially when i used Android default layout for the list, list items were displayed but not anymore... I don't understand what I'm doing wrong. Can anyone help?
Here is the group_view.xml file
<?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"
android:padding="30dp" >
<TextView
android:id="#+id/gName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Group Name"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_marginRight="100dp"
android:textStyle="bold" />
<TextView
android:id="#+id/activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/signIn"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:text="5"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textStyle="bold" />
</LinearLayout>
You can replace all your code by next
stringArray = new String[10];
groupItemArrayAdapter = new GroupAdapter(this,stringArray);
groupListView = (ListView) findViewById(R.id.mainList);
groupListView.setAdapter(new ArrayAdapter<String>(this, R.layout.group_view, R.id.gName, stringArray));
it's for case when you want to show strings at gName field, if you want to shot them at activity, then you need to use
groupListView.setAdapter(new ArrayAdapter<String>(this, R.layout.group_view, R.id.activity, stringArray));
Answer for "Why it's blank?"
#Override
public View getView(int position, View convertView, ViewGroup parent){
return inflater.inflate(R.layout.group_view,parent,false);
}
You only inflate empty view and does not assign strings to fields. It would be (simplest version)
#Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = inflater.inflate(R.layout.group_view, parent, false);
TextView textView = (TextView)convertView.findViewById(R.id.gName);
String item = getItem(position)
textView.setText(item);
return convertView;
}
You'll be able to implement better version after read article Making ListView Scrolling Smooth

ListView items drawn on top of each other when scrolling (Android)

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();

Using customlistviews in android : Keep on getting list view = NULL

I am new to android and am trying to create two fragments and have it so you can slide between the two, one is a list and the otehr a grid. I had the list working when it when I was using an ArrayAdapter and had my EventListFragment extending ListFragment (if code is helpful let me know and ill post that part)
I am now trying to create a custom list view with multiline list items (let me know if there is an easier way and if i have simply overcomplicated the whole thing)
Here is my code:
Event List Fragment:
public class EventListFragment extends Fragment {
ArrayList<EventObject> eventObjects;
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
eventObjects = ((EventsActivity)getActivity()).getEventObjects();
View view = inflater.inflate(R.layout.eventgrid ,container,false);
Listview listView = (ListView) view.findViewById(R.id.listView);
if (listView == null) {
System.out.println("asas");
}
listView.setAdapter(new MyCustomBaseAdapter(getActivity().getBaseContext(), eventObjects));
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
Object o = listView.getItemAtPosition(position);
EventObject fullObject = (EventObject)o;
System.out.println("asd");
}
});
return view;
}
}
The corresponding xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<ListView
android:id="#+id/listView"
android:layout_height="wrap_content"
android:layout_width="fill_parent"/>
</RelativeLayout>
The xml for the customgridrow:
<?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:layout_height="fill_parent">
<TextView android:id="#+id/name"
android:textSize="14sp"
android:textStyle="bold"
android:textColor="#FFFF00"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/cityState"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
EDIT
The getView() from MyCustomBaseAdapter :
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.customgridrow, null);
holder = new ViewHolder();
holder.txtName = (TextView) convertView.findViewById(R.id.name);
holder.txtCityState = (TextView) convertView.findViewById(R.id.cityState);
holder.txtPhone = (TextView) convertView.findViewById(R.id.phone);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.txtName.setText(events.get(position).getName());
holder.txtCityState.setText(events.get(position).getDate());
holder.txtPhone.setText(events.get(position).getVenue());
return convertView;
}
From your comments
You are inflating the wrong layout
You should inflate the one that has listview and initialize the same.
Change
View view = inflater.inflate(R.layout.eventgrid ,container,false);
to
View view = inflater.inflate(R.layout.eventList ,container,false);
Every time you want to add an object to a list, you have to provide a view for the object. Android asks your list adapter, be it custom or system-defined, it asks the adapter what each list item is supposed to look like. This is where getView() comes into play.
public abstract View getView (int position, View convertView, ViewGroup parent):
Get a View that displays the data at the specified position in the data set.
If convertView is null, you will get an NPE.
Tutorials here: http://www.javacodegeeks.com/2013/06/android-listview-tutorial-and-basic-example.html

android.widget.ArrayAdapter<T> just accept row template

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.

Adding dynamic ExpandableListView inside main.xml

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

Categories

Resources