Android listview lagging with complex layout - android

Like the title say, i create list view which each item display image, three line text, and a button, but the view is so lagging even in samsung galaxy mega dual core, here my item view xml
<RelativeLayout
android:gravity="center_vertical"
android:padding="5.0dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="?android:listPreferredItemHeight"
xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:id="#+id/compositeListViewItemThumbnailImage"
android:layout_width="60.0dip"
android:layout_height="60.0dip"
android:src="#drawable/ic_launcher"
android:scaleType="fitCenter"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignWithParentIfMissing="true"
android:contentDescription="#string/_empty_strings" />
<LinearLayout
android:orientation="vertical"
android:id="#+id/compositeListViewItemFirstLinearLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/compositeListViewItemThumbnailImage"
android:layout_alignTop="#+id/compositeListViewItemThumbnailImage"
android:layout_alignBottom="#+id/compositeListViewItemThumbnailImage"
android:layout_alignParentRight="true">
<TextView
android:textSize="16.0sp"
android:gravity="center_vertical"
android:id="#+id/compositeListViewItemFirstLineText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello_world"
android:singleLine="true"
android:ellipsize="marquee"
android:lines="1"
android:inputType="textNoSuggestions" />
<TextView
android:textSize="12.0sp"
android:id="#+id/compositeListViewItemSecondLineText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello_world"
android:singleLine="true"
android:ellipsize="marquee"
android:lines="1"
android:inputType="textNoSuggestions" />
<TextView
android:textSize="14.0sp"
android:singleLine="true"
android:ellipsize="marquee"
android:lines="1"
android:layout_gravity="center_vertical"
android:id="#+id/compositeListViewItemThirdLineText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello_world"
android:inputType="textNoSuggestions" />
</LinearLayout>
<Button
android:id="#+id/compositeListViewItemActionButton"
android:paddingLeft="5.0dip"
android:paddingTop="5.0dip"
android:paddingRight="5.0dip"
android:paddingBottom="5.0dip"
android:focusable="false"
android:layout_width="wrap_content"
android:layout_height="30.0dip"
android:layout_marginTop="30.0dip"
android:layout_marginRight="0.0dip"
android:text="#string/hello_world"
android:layout_alignParentRight="true"
style="?android:attr/buttonStyleSmall" />
</RelativeLayout>
as it might / might not be affected by the adapter view, i also put it here
public class SimpleAdapter extends ArrayAdapter implements Serializable {
private ArrayList<?> items;
private int itemLayout;
private String[] itemFieldsName;
private int[] itemElements;
private Context ctx;
public SimpleAdapter(Context ctx, ArrayList<?> items, int itemLayout, int[] itemElements, String[] itemFieldsName) {
super(ctx, itemLayout, items);
this.items = items;
this.itemElements = itemElements;
this.itemLayout = itemLayout;
this.itemFieldsName = itemFieldsName;
this.ctx = ctx;
}
public View getView(int position, View convertView, ViewGroup parent) {
View itemView = convertView;
if (itemView == null) {
itemView = ((LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(this.itemLayout, null);
}
Object item = this.items.get(position);
for (int i = 0; i < this.itemElements.length; i++) {
Object value = getValue(item, Character.toUpperCase(this.itemFieldsName[i].charAt(0)) + this.itemFieldsName[i].substring(1));
View elementView = null;
if (itemView != null) {
elementView = itemView.findViewById(this.itemElements[i]);
if ((elementView instanceof TextView)) {
((TextView) elementView).setText(value.toString());
} else if ((elementView instanceof SmartImageView)) {
((SmartImageView) elementView).setImageUrl(value.toString());
} else if ((elementView instanceof Button)) {
((Button) elementView).setText(value.toString());
}
}
}
return itemView;
}
private Object getValue(Object obj, String fieldName) {
ArrayList<String> fieldsName = new ArrayList<String>();
int length;
String str = Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
Object value = new Object();
try {
value = obj.getClass().getMethod("get" + str, new Class[0]).invoke(obj);
} catch (Exception ex) {
value = fieldName;
}
return value;
}
private String trimString(String string, int length, boolean soft) {
if(string == null || string.trim().isEmpty()){
return string;
}
StringBuffer sb = new StringBuffer(string);
int actualLength = length - 3;
if(sb.length() > actualLength){
if(!soft)
return sb.insert(actualLength, "...").substring(0, actualLength+3);
else {
int endIndex = sb.indexOf(" ",actualLength);
return sb.insert(endIndex,"...").substring(0, endIndex+3);
}
}
return string;
}
}
Can someone tell me where i was wrong?,
tell me if you need more explanation / code resource

Finding an inner view inside an inflated layout is among the most common operations in Android. This is usually done through a View method called findViewById(). This method will recursively go through the view tree looking for a child with a given IDcode. Using findViewById() on static UI layouts is totally fine but, as you’ve seen, ListView calls the adapter’s getView() very frequently when scrolling. findViewById() might perceivably hit scrolling performance in ListViews—especially if your row layout is non-trivial.
The View Holder pattern is about reducing the number of findViewById() calls in the adapter’s getView(). In practice, the View Holder is a lightweight inner class that holds direct references to all inner views from a row. You store it as a tag in the row’s view after inflating it. This way you’ll only have to use findViewById() when you first create the layout. Here’s the code sample with View Holder pattern applied:
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.your_layout, null);
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.text);
convertView.setTag(holder);
} else {
holder = convertView.getTag();
}
holder.text.setText("Position " + position);
return convertView;
}
private static class ViewHolder {
public TextView text;
}

There is one known issue with android:singleLine where it kills performance on ListViews drastically. Please see this question Why does android:singleLine="true" make ListView scrolling very laggy?
Remove it from your layout and use maxLines instead.

Related

textview of listview in android

I have Listview that contains a Textview, I populate data from sqlite inside them , now I want to change the textview background color for each row based on the value in each one.
I couldn't do it , can anybody help me for how to get each textview from the listview ??
Edit :
Here is my code to populate the listview:
sql = new SqlCommands(getApplicationContext());
Fields = new String[]{SqlCommands.Group, SqlCommands.Subject, SqlCommands.Body, SqlCommands.DateTime};
int [] Dview = new int []{R.id.grop, R.id.sbj,R.id.bdy,R.id.DT};
Cursor c = sql.GetData();
Adpt = new SimpleCursorAdapter(getApplicationContext(),R.layout.items, c , Fields, Dview ,0 );
NotiLst.setAdapter(Adpt);
this is the XML file for the items :
<?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="horizontal"
android:background="#drawable/grp_shap" >
<ImageView android:id="#+id/Prio"
android:layout_width="32dip"
android:layout_height="32dip"
/>
<TextView
android:id="#+id/grop"
android:layout_width="64sp"
android:layout_height="40sp"
android:layout_alignBottom="#+id/Prio"
android:layout_alignParentLeft="true"
android:text="S"
android:textSize="12sp" />
<TextView
android:id="#+id/DT"
android:layout_width="wrap_content"
android:layout_height="14sp"
android:layout_alignParentRight="true"
android:layout_alignTop="#id/title"
android:gravity="right"
android:text="Date Rec"
android:layout_marginRight="5dip"
android:textSize="12sp"
/>
<TextView
android:id="#+id/bdy"
android:layout_width="fill_parent"
android:layout_height="28sp"
android:layout_below="#+id/DT"
android:layout_toLeftOf="#+id/hi"
android:layout_toRightOf="#+id/Prio"
android:text="Body"
android:textSize="12sp" />
<TextView
android:id="#+id/sbj"
android:layout_width="fill_parent"
android:layout_height="12sp"
android:layout_alignLeft="#+id/bdy"
android:layout_alignParentTop="true"
android:layout_alignRight="#+id/bdy"
android:fontFamily="sans-serif"
android:text="Subject"
android:textSize="12sp" />
<ImageView
android:id="#+id/hi"
android:layout_width="20dip"
android:layout_height="26dip"
android:layout_alignLeft="#+id/DT"
android:layout_below="#+id/DT"
android:layout_marginLeft="15dp"
android:src="#drawable/highprio" />
</RelativeLayout>
and I have a listview on the activity_mail layout which populated whith this items.
I want to change the color for the textview with id grop based on the value inserted on it
You should use a custom adapter:
public class MyAdapter extends BaseAdapter {
private static class ViewHolder {
public final TextView mTv;
}
private final Context mContext;
private final List<String> mList; //you can change this to String array
public MyAdapter (Context context, List<String> list) {
this.mContext = context;
this.mList= list;
}
#Override
public int getCount() {
return mList.size();
}
#Override
public String getItem(int position) {
return mList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder h;
final String string = mList.get(position);
if (convertView == null) {
convertView = View.inflate(mContext, R.layout.item_listview, null);
h = new ViewHolder();
h.mTv= (TextView) convertView .findViewById(R.id.mTvRes);
convertView.setTag(h);
} else {
h = (ViewHolder) convertView.getTag();
}
h.mTv.setText....
h.mTv.setTextColor....
h.mTv.setBackground....
return convertView;
}
}
in your activity:
List<String> list = Arrays.asList(Fields);
MyAdapter adapter = new MyAdapter(this, list);
NotiLst.setAdapter(adapter);
I didn't checked it and you maybe need to do some changes but it should work.
If you have something like this:
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if(convertView == null) {
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(resource, parent, false);
viewHolder = new ViewHolder();
viewHolder.label = (TextView) convertView.findViewById(android.R.id.text1);
viewHolder.label.setBackground(getResources().getColor(color.white));
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.label.setText(activitiesList.get(position).getName());
return convertView;
}

Is it possible to customize preference-header layout?

I have found similar questions, but can't find a specific answer that is up-to-date.
I'm using <preference-header>, as per 3.0+ settings design guidelines ( I target 4.1.2+) to build my headers; I want to set a custom layout to these headers. Note that I don't want to fall back to the old PreferenceScreen method as described here, because I don't support older Android version.
As far as I could research, this layout is held by a private member of the PreferenceActivity class, and it's retrieved with a styleable attribute that doesn't seem publicly accessible:
private int mPreferenceHeaderItemResId = 0;
...
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
...
TypedArray sa = obtainStyledAttributes(null,
com.android.internal.R.styleable.PreferenceActivity,
com.android.internal.R.attr.preferenceActivityStyle,
0);
...
mPreferenceHeaderItemResId = sa.getResourceId(
com.android.internal.R.styleable.PreferenceActivity_headerLayout,
com.android.internal.R.layout.preference_header_item);
...
}
This resource is then passed to a private Adapter to populate the header ListView.
Is there a way to pass a different layout resource?
UPDATE 14.4.2016: there was problem with recreate by savedInstanceState, but I found another similar solution from which I used setListAdapter method code (I modified the code below).
I solve this problem just too. I don't know if the following solution is correct, but was the fastest. Because PreferenceActivity is child of ListActivity, you can override setListAdapter method for using own adapter for header items. This is ugly hack, because setListAdapter method is called in PreferenceActivity.onCreate() with sets adapter parameter to new instance of HeaderAdapter, so following adjustment ignore this instance.
#Override
public void setListAdapter(ListAdapter adapter) {
int i, count;
if (mHeaders == null) {
mHeaders = new ArrayList<>();
// When the saved state provides the list of headers, onBuildHeaders is not called
// so we build it from the adapter given, then use our own adapter
count = adapter.getCount();
for (i = 0; i < count; ++i) {
mHeaders.add((Header) adapter.getItem(i));
}
}
super.setListAdapter(new CustomHeaderAdapter(this, mHeaders, R.layout.preference_header_item, true));
}
mHeaders property is defined as class member
private List<Header> mHeaders;
and is assigned in onBuildHeaders:
#Override
public void onBuildHeaders(List<Header> target) {
mHeaders = target;
loadHeadersFromResource(R.xml.preference_headers, target);
...
}
I copied and modified adapter inner class and layout from SDK source:
private static class CustomHeaderAdapter extends ArrayAdapter<Header> {
private static class HeaderViewHolder {
ImageView icon;
TextView title;
TextView summary;
}
private LayoutInflater mInflater;
private int mLayoutResId;
private boolean mRemoveIconIfEmpty;
public CustomHeaderAdapter(Context context, List<Header> objects, int layoutResId,
boolean removeIconBehavior) {
super(context, 0, objects);
mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mLayoutResId = layoutResId;
mRemoveIconIfEmpty = removeIconBehavior;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
HeaderViewHolder holder;
View view;
if (convertView == null) {
view = mInflater.inflate(mLayoutResId, parent, false);
holder = new HeaderViewHolder();
holder.icon = (ImageView) view.findViewById(R.id.icon);
holder.title = (TextView) view.findViewById(R.id.title);
holder.summary = (TextView) view.findViewById(R.id.summary);
view.setTag(holder);
} else {
view = convertView;
holder = (HeaderViewHolder) view.getTag();
}
// All view fields must be updated every time, because the view may be recycled
Header header = getItem(position);
if (mRemoveIconIfEmpty) {
if (header.iconRes == 0) {
holder.icon.setVisibility(View.GONE);
} else {
holder.icon.setVisibility(View.VISIBLE);
holder.icon.setImageResource(header.iconRes);
}
} else {
holder.icon.setImageResource(header.iconRes);
}
holder.title.setText(header.getTitle(getContext().getResources()));
CharSequence summary = header.getSummary(getContext().getResources());
if (!TextUtils.isEmpty(summary)) {
holder.summary.setVisibility(View.VISIBLE);
holder.summary.setText(summary);
} else {
holder.summary.setVisibility(View.GONE);
}
return view;
}
}
preference_header_item.xml with modified minHeight:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="64dp"
android:background="?android:attr/activatedBackgroundIndicator"
android:gravity="center_vertical"
android:paddingRight="?android:attr/scrollbarSize"
android:paddingEnd="?android:attr/scrollbarSize">
<ImageView
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6dip"
android:layout_marginEnd="6dip"
android:layout_gravity="center" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dip"
android:layout_marginStart="2dip"
android:layout_marginRight="6dip"
android:layout_marginEnd="6dip"
android:layout_marginTop="6dip"
android:layout_marginBottom="6dip"
android:layout_weight="1">
<TextView android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
<TextView android:id="#+id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#android:id/title"
android:layout_alignLeft="#android:id/title"
android:layout_alignStart="#android:id/title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:ellipsize="end"
android:maxLines="2" />
</RelativeLayout>
</LinearLayout>

Personalized Listview error on set background color

i have a problem in my app:
i use a listview with a personalized adapter,
in this adapter i want to change the color of the line depending on whether the message is read or not.
In the metod GETVIEW i control a variable, if it is equal to 0 i want to change the background color.
All works and the list is displayed as i want,
but when there are a lot of elements and the list is scrolled in any direction (from top to bottom and vice versa) the raws are displeyed with the same color even if by code is set another color.
Has anyone ever had the same problem?
You can advise me something about it?
There is the code of my Adapter:
public class LazyAdapterComunicazioni extends BaseAdapter {
private Activity activity;
private String[] id;
private String[] titolo;
private String[] data;
private String[] letto;
private static LayoutInflater inflater=null;
//public ImageLoader imageLoader;
public LazyAdapterComunicazioni(Activity a, String[] idCom, String[] titoloCom, String[] dataCom, String[]lettoCom) {
activity = a;
id = idCom;
titolo = titoloCom;
data = dataCom;
letto = lettoCom;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return id.length;
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if(convertView == null)
{
vi = inflater.inflate(R.layout.comunicazionicslist, null);
}
ContactsViewHolder viewHolder = new ContactsViewHolder();
//Settimane
viewHolder.txtTitolo=(TextView)vi.findViewById(R.id.comCS_Titolo);
viewHolder.txtTitolo.setText(titolo[position].toString());
//Data
viewHolder.txtData=(TextView)vi.findViewById(R.id.comCS_Data);
viewHolder.txtData.setText(data[position].toString());
//ID
viewHolder.txtID=(TextView)vi.findViewById(R.id.comCS_ID);
viewHolder.txtID.setText(id[position].toString());
//Connessianne e Apretura del DB
String read = letto[position].toString();
if (read.equals("0")) //DA LEGGERE
{
//LAYOUT
viewHolder.rel = (RelativeLayout)vi.findViewById(R.id.comCS_RIGA);
viewHolder.rel.setBackgroundResource(R.drawable.sfondorigacomcs);
viewHolder.txtTitolo.setTextColor(Color.WHITE);
}
return vi;
}
static class ContactsViewHolder {
TextView txtTitolo;
TextView txtData;
TextView txtID;
RelativeLayout rel;
}
}
and the xml of the single row:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="#+id/comCS_RIGA"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#ffffff"
android:paddingTop="10dp"
android:paddingBottom="10dp"
>
<TextView
android:id="#+id/comCS_Data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textColor="#000000"
android:layout_alignParentLeft="true"
android:layout_marginLeft="16dp"
android:textSize="12sp"
/>
<TextView
android:id="#+id/comCS_ID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/comCS_Data"
android:visibility="invisible"
/>
<TextView
android:id="#+id/comCS_Titolo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/comCS_Data"
android:layout_marginTop="2dp"
android:layout_marginLeft="16dp"
android:text=""
android:textColor="#357cbc"
android:textSize="18sp"
/>
<ImageView
android:id="#+id/feedbackCars_Positivo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/frecciacom"
android:contentDescription="#string/title_Comunicazioni"
android:layout_alignParentRight="true"
android:layout_marginTop="2dp"
android:layout_marginRight="16dp"
/>
</RelativeLayout>
It's a common error.
Views are recycled so you have to set back default values in any cases.
if (read.equals("0")) //DA LEGGERE
{
//LAYOUT
viewHolder.rel = (RelativeLayout)vi.findViewById(R.id.comCS_RIGA);
viewHolder.rel.setBackgroundResource(R.drawable.sfondorigacomcs);
viewHolder.txtTitolo.setTextColor(Color.WHITE);
}
else {
viewHolder.rel.setBackgroundResource("you_defaulf_bg_res");
}
First of all, you are not using the ViewHolder pattern correctly. The ViewHolder is designed to hold references to the Views of the list-item and minimize the findViewById(...) calls.
That purpose is not fulfilled by your code. The reason for the behaviour you described lies in the Views not being recycled.
Do it like this:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
ContactsViewHolder viewHolder;
if(convertView == null) {
vi = inflater.inflate(R.layout.comunicazionicslist, null);
viewHolder = new ContactsViewHolder();
viewHolder.txtTitolo=(TextView)vi.findViewById(R.id.comCS_Titolo);
viewHolder.txtData=(TextView)vi.findViewById(R.id.comCS_Data);
viewHolder.txtID=(TextView)vi.findViewById(R.id.comCS_ID);
viewHolder.rel = (RelativeLayout)vi.findViewById(R.id.comCS_RIGA);
vi.setTag(viewHolder);
} else {
viewHolder = (ContactsViewHolder) vi.getTag();
}
//Settimane
viewHolder.txtTitolo.setText(titolo[position].toString());
//Data
viewHolder.txtData.setText(data[position].toString());
//ID
viewHolder.txtID.setText(id[position].toString());
//Connessianne e Apretura del DB
String read = letto[position].toString();
if (read.equals("0")) //DA LEGGERE {
viewHolder.rel.setBackgroundResource(R.drawable.sfondorigacomcs);
viewHolder.txtTitolo.setTextColor(Color.WHITE);
} else {
viewHolder.rel.setBackgroundResource(R.drawable.NORMAL_BACKGROUND);
}
return vi;
}

How to remove setAdapterList View

I am trying to implement list. Here is start.xml file which have a text box i which i am typing any word and a list of words will open containing this word:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/FrameLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<EditText
android:id="#+id/start_edit"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="top|left"
android:ems="10"
android:hint="Type to search"
android:paddingLeft="50dp" >
<requestFocus />
</EditText>
for list view i am using this ListView.xml file:
<ImageView
android:id="#+id/image_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="#drawable/abacus_thumbnail"
android:scaleType="centerCrop" />
<ImageView
android:id="#+id/imageView_color_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="#drawable/blue_thumbnail" />
<TextView
android:id="#+id/title_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/image_list"
android:layout_marginLeft="20dp"
android:layout_toRightOf="#+id/image_list"
android:gravity="center"
android:text="Abacus"
android:textColor="#000000"
android:textSize="30sp"
android:textStyle="bold"
android:typeface="sans" />
<TextView
android:id="#+id/textView_meaning_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/title_list"
android:layout_below="#+id/title_list"
android:layout_marginTop="10dp"
android:text="TextView"
android:textColor="#000000"
android:textSize="25sp" />
i am using EfficientAdapetr to convert one View from one to another when my app start the EditBox will be empty and a background image . I have ClickListner on list item when a word is type a list opens and when click on item this word will open. Now problem is that when i click on item of list the background populate with word but listView not remove. on Item click i want to open my background with the word.
Here is my code:
listAdapter = new EfficientAdapter2(this);
setListAdapter(listAdapter);
private class EfficientAdapter2 extends BaseAdapter implements Filterable,OnItemClickListener {
private Context context;
LayoutInflater inflater;
public EfficientAdapter2(Context context) {
this.context = context;
inflater = LayoutInflater.from(context);
}
public int getCount() {
// if(SearchWordString.isEmpty()==false)
// {
return SearchWordString.size();
/// }
//return 0;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
viewHolder2 holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.ListView, null);
holder = new viewHolder2();
// Log.i("View","is Null");
convertView.setTag(holder);
} else {
//Log.i("View","is not Null");
holder = (viewHolder2) convertView.getTag();
}
holder.word = (TextView) convertView.findViewById(R.id.title_list);
holder.meaning = (TextView) convertView
.findViewById(R.id.textView_meaning_list);
holder.image = (ImageView) convertView
.findViewById(R.id.image_list);
holder.image_color = (ImageView) convertView
.findViewById(R.id.imageView_color_list);
holder.cell = (RelativeLayout) convertView
.findViewById(R.id.RelativeLayout_list);
try {
"functionalty here"
} catch (IOException e) {
e.printStackTrace();
}
return convertView;
}
here is onItemClick:
protected void onListItemClick(ListView l, View v, int position, long id) {////////
super.onListItemClick(l, v, position, id);
//Log.i("Position",""+position);
changeEverything(position);// here i am converting my ListView to
Start.xml but its on happening
motherOfIndex = position;
}
first debug your app and check weather onListItemClick() event firing. this won't fire if you have clickable items in your listView. if that's the case you have to set isClickable=false for all the items in ListView.xml file. in order to dismiss the the listView, you have to set it's visibility to View.GONE
However if you want to popup a suggestion list when something type on a EditText, this is not the best practice to do that. you can use a AutoCompleteTextView and directly set your ListView adapter to it. they it will create a listView for your and will automatically handle the set selected text to the AutoCompleteTextView and will dismiss the listView

getView() method of ArrayAdapter repeats first two or three items in list

I extended an ArrayAdapter with an overridden getView() method to fill my ListView object, but the adapter will grab the first two or three objects from the ArrayList I pass to it, then just repeat those in seemingly random order for the entire length of the list. Furthermore, when I scroll up and down in the ListView, some rows change from one list item to another. The ArrayList<Credit> object gets populated from a JSONObject, and to the best of my knowledge is correct prior to being passed into the ArrayAdapter.
My custom ArrayAdapter
private class CreditArrayAdapter extends ArrayAdapter<Credit> {
private ArrayList<Credit> credits;
private int creditCount;
public CreditArrayAdapter(Context ctx, int textViewResourceId, List<Credit> items) {
super(ctx, textViewResourceId, items);
credits = (ArrayList<Credit>) items;
creditCount = credits.size();
}
#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.list_item_movie_medium, null);
Credit current = credits.get(position);
Log.d(tag, "current credit: " + current.toString());
ImageView creditPicture = (ImageView) v.findViewById(R.id.image_poster_thumbnail);
try {
creditPicture.setImageBitmap(current.getPosterSmall());
} catch(Exception e) {
Log.d(tag, "failed to set cast member picture");
e.printStackTrace();
}
TextView castMemberName = (TextView) v.findViewById(R.id.text_credit_info);
castMemberName.setText(current.toString());
}
return v;
}
#Override
public int getCount() {
return creditCount;
}
}
being called by:
appearsIn = (ListView) findViewById(R.id.listview_appears_in);
List<Credit> credits = searcher.getCreditsByPersonId(personId);
CreditArrayAdapter creditAdapter = new CreditArrayAdapter(getBaseContext(), R.layout.list_item_movie_medium, credits);
creditAdapter.notifyDataSetChanged();
appearsIn.setAdapter(creditAdapter);
The layout containing the ListView:
<?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="wrap_content"
android:orientation="vertical"
android:layout_centerHorizontal="true"
android:weightSum="2">
<ScrollView android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView android:id="#+id/image_person_info"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:contentDescription="person image"/>
<TextView android:id="#+id/text_person_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30dp"/>
<TextView android:id="#+id/text_person_birth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"/>
<TextView android:id="#+id/text_person_death"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"/>
<TextView android:id="#+id/text_person_bio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16dp"/>
</LinearLayout>
</ScrollView>
<ListView android:id="#+id/listview_appears_in"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"/>
</LinearLayout>
My list item layout:
<?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="horizontal">
<ImageView android:id="#+id/image_poster_thumbnail"
android:layout_height="wrap_content"
android:layout_width="wrap_content"/>
<TextView android:id="#+id/text_credit_info"
android:layout_height="wrap_content"
android:layout_width="fill_parent"/>
</LinearLayout>
change the getView like this:
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.list_item_movie_medium, null);
}
Credit current = credits.get(position);
Log.d(tag, "current credit: " + current.toString());
ImageView creditPicture = (ImageView) v.findViewById(R.id.image_poster_thumbnail);
try {
creditPicture.setImageBitmap(current.getPosterSmall());
} catch(Exception e) {
Log.d(tag, "failed to set cast member picture");
e.printStackTrace();
}
TextView castMemberName = (TextView) v.findViewById(R.id.text_credit_info);
castMemberName.setText(current.toString());
return v;
}
Your problem was you were not doing all the code you needed to set the View object correctly when convertView was != null.
Use this snippet:
#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.list_item_movie_medium, null);
}
Credit current = credits.get(position);
Log.d(tag, "current credit: " + current.toString());
ImageView creditPicture = (ImageView) v.findViewById(R.id.image_poster_thumbnail);
try {
creditPicture.setImageBitmap(current.getPosterSmall());
} catch(Exception e) {
Log.d(tag, "failed to set cast member picture");
e.printStackTrace();
}
TextView castMemberName = (TextView) v.findViewById(R.id.text_credit_info);
castMemberName.setText(current.toString());
return v;
}
try adjust your xml layout on anyone place that references the height, because the android will do a measure to draw eachtime and will redraw the cell up again.
Try use on listview match_parent and on cell at row an exactly height.
sorry my bad english.

Categories

Resources