When the statement convertView = mInflater.inflate(R.layout.listitem_course, null); execute in the following overridden method of BaseAdapter the app stops. I dont know why.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.i(StudyManagerDataSource.LOG_TAG,
"CourseListAdapter -> getView called!");
if (convertView == null) {
Log.i(StudyManagerDataSource.LOG_TAG,
"CourseListAdapter -> Convet view is null called 1!");
convertView = mInflater.inflate(R.layout.listitem_course, null);
mViewHolder = new ViewHolder();
mViewHolder.courseNameTextView = (TextView) convertView
.findViewById(R.id.courseNameTextView);
convertView.setTag(mViewHolder);
} else {
mViewHolder = (ViewHolder) convertView.getTag();
}
Course mCourse = mCourses.get(position);
mViewHolder.courseNameTextView.setText(mCourse.getCourseName());
Log.i(StudyManagerDataSource.LOG_TAG,
"CourseListAdapter -> getView executed!");
return convertView;
}
The code for listitem_course is as follows:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/courseNameTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp" />
</LinearLayout>
You should use this to inflate your item:
mInflater.inflate(R.layout.listitem_course, parent, false);
EDIT:
The parent is the ViewGroup in which your inflated view will be inserted, in your case, the parent argument from the getView() method..
Related
I am having custom adapter with item with checkbox and textview. Here is the layout of the item:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="#dimen/standard_margin"
>
<CheckBox
android:id="#+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:focusable="false"
android:focusableInTouchMode="false"
/>
<TextView
android:id="#+id/checkBoxDesc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:layout_marginLeft="#dimen/new_small_margin"
android:layout_alignBaseline="#+id/isEbank"
android:layout_alignBottom="#+id/isEbank"
android:layout_toRightOf="#+id/isEbank"
android:layout_alignTop="#+id/isEbank"
android:gravity="left"
android:focusable="false"
android:focusableInTouchMode="false"
/>
Here is how the list looks like:
I like when user clicks on list item , or on checkbox to perform same action. However onItemClick does not fire when user clicks on item.
Here is my code for the view:
#Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
View mRoot = inflater.inflate(R.layout.fragment_user, container, false);
ArrayList<Option> listOptions=new ArrayList<Option>();
Option optionYes=new Option(true,getResources().getString(R.string.Yes));
listOptions.add(optionYes);
Option optionNo=new Option(false,getResources().getString(R.string.No));
listOptions.add(optionNo);
listView=(ListView)mRoot.findViewById(R.id.lst);
adapter=new OptionAdapter(getActivity(),R.layout.item_option,listOptions);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
CheckBox box = (CheckBox) view.findViewById(R.id.checkBox1);
box.setChecked(true);
}
});
return mRoot;
}
Here is my code for the adapter:
#Override
public View getView(int position, View convertView, final ViewGroup parent) {
final Option selectedOption = optionsList.get(position);
ViewHolder holder = null;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.item_option, null);
holder = new ViewHolder();
holder.optionDesc = (TextView) convertView.findViewById(R.id.optionDesc);
holder.optionDesc.setText(selectedOption.getDesc());
holder.optionCheckBox = (CheckBox) convertView.findViewById(R.id.isEbank);
holder.optionCheckBox.setFocusable(false);
holder.optionCheckBox.setFocusableInTouchMode(false);
convertView.setTag(holder);
holder.optionCheckBox.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
});
} else {
holder = (ViewHolder) convertView.getTag();
}
return convertView;
}
However it does not work.
you should disable user interaction add this to xml
android:clickable="false"
I suggest you to do this inside getView like here
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.item_option, null);
holder = new ViewHolder();
holder.name = (CheckBox) convertView.findViewById(R.id.checkBox1);
convertView.setTag(holder);
holder.name.setOnClickListener( new View.OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v ;
//Check if cb is checked or not here
cb.isChecked();
});
}
else {
holder = (ViewHolder) convertView.getTag();
}
}
When I click on listview, it will change that item to different layout. But after that I can't click on that item anymore. What am I supposed to do? Please help me. Thank you.
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null || convertView.getTag() == null) {
convertView = inflater.inflate(R.layout.activity_mainlist_item, parent, false);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
holder.rl_item.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectedItem(position);
notifyDataSetChanged();
Intent intent = new Intent(mContext.getApplicationContext(), DetailActivity.class);
mContext.startActivity(intent);
}
});
if (this.clk_position == position) {
View view = inflater.inflate(R.layout.activity_mainlist_item_p, null);
return view;
}
return convertView;
}
I suggest using single layout and divide it into two sections. First section will be visible by default and second section will be invisible. When you click on list item, make first section invisible and second section visible.
For example,
list_item_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- replace below TextView with the layout of activity_mainlist_item.xml -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="Layout 1"
android:id="#+id/layout1"
android:background="#android:color/holo_blue_bright"
/>
<!-- replace below TextView with the layout activity_mainlist_item_p.xml and don't forget to set android:visibility="gone" -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="Layout 2"
android:id="#+id/layout2"
android:visibility="gone"
android:background="#android:color/holo_purple"
/>
</LinearLayout>
In getView(), try as below
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null || convertView.getTag() == null) {
convertView = inflater.inflate(R.layout.list_item_layout, parent, false);
holder = new ViewHolder(convertView);
// Assuming `ViewHolder` has layout1 and layout2.
holder.layout1 = (TextView) convertView.findViewById(R.id.layout1);
holder.layout2 = (TextView) convertView.findViewById(R.id.layout2);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
holder.rl_item.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectedItem(position);
notifyDataSetChanged();
Intent intent = new Intent(mContext.getApplicationContext(), DetailActivity.class);
mContext.startActivity(intent);
}
});
if (this.clk_position == position) {
// Here, set swap the visibility or vice versa depending on your conditions
holder.layout1.setVisibility(View.GONE);
holder.layout2.setVisibility(View.VISIBLE);
return view;
}
return convertView;
}
I am trying to build a layout as shown in the image where the Date(TextView) is shown above the images in GridView and the TextView appears multiple times in view .I am confused on how to implement it. I tried putting TextView in list item but in that case TextView is repeating for each row. Can anyone suggest how to go with this.Reference image attached.
main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/lvTimeline"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayout>
list_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/rlText">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="28 Feb"
android:layout_marginLeft="16dp"
android:layout_alignParentLeft="true"
android:id="#+id/tvDate"/>
</RelativeLayout>
<GridView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/gvTest"
android:numColumns="3"
android:verticalSpacing="3dp">
</GridView>
gridview_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="116dp"
android:layout_height="116dp"
android:scaleType="fitXY"
android:id="#+id/ivTimeline"
android:src="#android:drawable/sym_def_app_icon"/>
List adapter:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
ViewHolder holder;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) parent.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.list_item, parent, false);
holder = new ViewHolder();
holder.tvDate = (TextView) view.findViewById(R.id.tvDate);
holder.gvTimeline = (GridView) convertView
.findViewById(R.id.gvTest);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.gvTimeline.setAdapter(new GridAdapter(imagesList));
return view;
}
public static class ViewHolder {
TextView tvDate;
GridView gvTimeline;
}
GridView Adapter :
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
ViewHolder holder;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) parent.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.gridview_item, parent, false);
holder = new ViewHolder();
holder.ivImage = (ImageView) view.findViewById(R.id.ivTimeline);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.ivImage.setImageResource(getItem(position));
return view;
}
public static class ViewHolder {
ImageView ivImage;
}
Image which I am getting now :
I have a problem. When i scrolling my gridView Images changes their place. GetView code. Thx
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.list_row_layout, null);
holder = new ViewHolder();
holder.imageView = (ImageView) convertView.findViewById(R.id.thumbImage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
ListItem newsItem = listData.get(position);
if (holder.imageView != null) {
new ImageDownloaderTask(holder.imageView).execute(newsItem.getUrl());
}
return convertView;
}
Element layout. It was first listView. Im using list adapter for gridView.
list_row_layout.xml
<?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="fill_parent"
android:background="#ff34495e"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:paddingTop="-24dp"
android:paddingBottom="-24dp">
<ImageView
android:id="#+id/thumbImage"
android:layout_width="360dp"
android:layout_height="360dp"
android:adjustViewBounds="false"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="false"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="false"
android:src="#drawable/placeholder" />
</RelativeLayout>
ListView and GridView recycle items when they are not visible anymore, so if your ImageView isn't being set with the image correctly you will have problems.
The only place you set the image in "holder.imageView" is apparently inside ImageDownloaderTask, so you must have a problem inside that class.
Or it isn't setting holder.imageView correctly or it is taking too long to download the image and to replace the older one.
Try this:
if (holder.imageView != null) {
holder.imageView.setImageDrawable(null);
new ImageDownloaderTask(holder.imageView).execute(newsItem.getUrl());
}
This won't make things right but you will see more clearly when the ImageDownloaderTask class is working and when it is not.
public View getView(int position, View convertView, ViewGroup parent){
// TODO Auto-generated method stub
View v;
if(convertView==null)
{
LayoutInflater li = getLayoutInflater();
v = li.inflate(R.layout.icontext, null);
}else{
v = convertView;
}
TextView tv = (TextView)v.findViewById(R.id.icon_text);
tv.setText(providers[position]);
ImageView iv = (ImageView)v.findViewById(R.id.icon_image);
iv.setImageResource(R.drawable.icon);
return v;
}
In my app I have a GridView inside ViewPager.
I am not using anywhere match_parent or wrap_content. I am using values like 200dp or 150dp. So why is my getView() of GridView adapter is calling multiple times?
I searched a lot like here,
here, here, and here.
This is my adapter class.
public class CustomGridViewAdapter1 extends BaseAdapter {
ArrayList<Integer> list2 = new ArrayList<Integer>();
private LayoutInflater mInflater;
public CustomGridViewAdapter1(Context context, ArrayList<Integer> list2) {
mInflater = LayoutInflater
.from(context.getApplicationContext());
this.list2 = list2;
}
#Override
public int getCount() {
return 6;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
try {
View hView = convertView;
if (convertView == null) {
hView = mInflater.inflate(R.layout.greeditem, null);
ViewHolder1 holder = new ViewHolder1();
holder.song_pic = (ImageView) hView.findViewById(R.id.pic1);
holder.name = (TextView) hView
.findViewById(R.id.tabletext1);
holder.layout = (LinearLayout) hView
.findViewById(R.id.bingo_rlayout1);
hView.setTag(holder);
}
ViewHolder1 holder = (ViewHolder1) hView.getTag();
imageLoader.DisplayImage(list1.get(position), holder.song_pic);
holder.name.setText(list.get(position));
if (list2.get(position) == 1) {
holder.layout.setBackgroundColor(getActivity()
.getResources().getColor(R.color.lightblue));
holder.name.setTextColor(getActivity().getResources().getColor(R.color.white));
}
return hView;
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
And this is my XML 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" >
<GridView
android:id="#+id/gridView1"
android:layout_width="320dp"
android:layout_height="250dp"
android:layout_below="#+id/ticketText"
android:numColumns="2"
android:background="#fff"
android:listSelector="#android:color/white">
</GridView>
<TextView
android:id="#+id/scoreId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/ticketText"
android:layout_alignBottom="#+id/ticketText"
android:layout_alignParentRight="true"
android:layout_marginRight="32dp"
android:text="Score 1/6"
android:textColor="#000000"
android:textSize="16sp" />
<TextView
android:id="#+id/ticketText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/tablayout"
android:layout_marginLeft="16dp"
android:text="My Ticket #1"
android:textColor="#000000"
android:textSize="16sp" />
</RelativeLayout>
We need to check the null condition in getView(). Try with below code:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolderItem viewHolder;
/*
* The convertView argument is essentially a "ScrapView" as described is Lucas post
* http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/
* It will have a non-null value when ListView is asking you recycle the row layout.
* So, when convertView is not null, you should simply update its contents instead of inflating a new row layout.
*/
if(convertView==null){
// inflate the layout
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
convertView = inflater.inflate(layoutResourceId, parent, false);
// well set up the ViewHolder
viewHolder = new ViewHolderItem();
viewHolder.textViewItem = (TextView) convertView.findViewById(R.id.textViewItem);
// store the holder with the view.
convertView.setTag(viewHolder);
}else{
// we've just avoided calling findViewById() on resource everytime
// just use the viewHolder
viewHolder = (ViewHolderItem) convertView.getTag();
}
// object item based on the position
ObjectItem objectItem = data[position];
// assign values if the object is not null
if(objectItem != null) {
// get the TextView from the ViewHolder and then set the text (item name) and tag (item ID) values
viewHolder.textViewItem.setText(objectItem.itemName);
viewHolder.textViewItem.setTag(objectItem.itemId);
}
return convertView;
}