i have a application with slidemenu that have some fragments in it
two custom adapter i used that both of them are same code and just one of them have a image more than another
customadapter file is:
package ir.monocode.az;
import ir.monocode.az.R;
import java.util.ArrayList;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Typeface;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
/********* Adapter class extends with BaseAdapter and implements with OnClickListener ************/
public class CustomAdapter extends BaseAdapter implements OnClickListener {
/*********** Declare Used Variables *********/
private Context activity;
private ArrayList data;
private static LayoutInflater inflater=null;
public Resources res;
CatsModel tempValues=null;
int i=0;
Context context;
Typeface face;
/************* CustomAdapter Constructor *****************/
public CustomAdapter(Context context, ArrayList d,Resources resLocal) {
/********** Take passed values **********/
activity = context;
data=d;
res = resLocal;
/*********** Layout inflator to call external xml layout () **********************/
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
/******** What is the size of Passed Arraylist Size ************/
public int getCount() {
if(data.size()<=0)
return 1;
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
/********* Create a holder to contain inflated xml file elements ***********/
public static class ViewHolder{
public TextView text;
public ImageView image;
}
/*********** Depends upon data size called for each row , Create each ListView row ***********/
public View getView(int position, View convertView, ViewGroup parent) {
View vii=convertView;
ViewHolder holder;
if(convertView==null){
/********** Inflate tabitem.xml file for each row ( Defined below ) ************/
vii = inflater.inflate(R.layout.catitems, null);
/******** View Holder Object to contain tabitem.xml file elements ************/
holder=new ViewHolder();
holder.text=(TextView)vii.findViewById(R.id.ctextView1);
holder.image=(ImageView)vii.findViewById(R.id.cimageView2);
Typeface typeface = Typeface.createFromAsset(holder.text.getContext().getAssets(),
"fonts/B YEKAN.TTF");
holder.text.setTypeface(typeface);
/************ Set holder with LayoutInflater ************/
vii.setTag(holder);
}
else
holder=(ViewHolder)vii.getTag();
if(data.size()<=0)
{
holder.text.setText("No Data");
}
else
{
/***** Get each Model object from Arraylist ********/
tempValues=null;
tempValues = (CatsModel) data.get(position);
/************ Set Model values in Holder elements ***********/
holder.text.setText(tempValues.getCatName());
int resID = activity.getResources().getIdentifier("icon"+tempValues.getImage() , "drawable", activity.getPackageName());
holder.image.setImageResource(resID);
/******** Set Item Click Listener for LayoutInflater for each row ***********/
vii.setOnClickListener(new OnItemClickListener(position));
}
return vii;
}
#Override
public void onClick(View v) {
Log.v("CustomAdapter", "=====Row button clicked");
}
/********* Called when Item click in ListView ************/
private class OnItemClickListener implements OnClickListener{
private int mPosition;
OnItemClickListener(int position){
mPosition = position;
}
#Override
public void onClick(View arg0) {
MainActivity sct = (MainActivity)activity;
sct.customonItemClick(mPosition);
}
}
}
articleadapter is:
package ir.monocode.az;
import ir.monocode.azmoonEstekhdami.R;
import java.util.ArrayList;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Typeface;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
/********* Adapter class extends with BaseAdapter and implements with OnClickListener ************/
public class ArticleAdapter extends BaseAdapter implements OnClickListener {
/*********** Declare Used Variables *********/
private Context activity;
private ArrayList data;
private static LayoutInflater inflater=null;
public Resources res;
ArticlesModel tempValues=null;
int i=0;
Context context;
Typeface face;
/************* CustomAdapter Constructor *****************/
public ArticleAdapter(Context context, ArrayList d,Resources resLocal) {
/********** Take passed values **********/
activity = context;
data=d;
res = resLocal;
/*********** Layout inflator to call external xml layout () **********************/
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
/******** What is the size of Passed Arraylist Size ************/
public int getCount() {
if(data.size()<=0)
return 1;
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
/********* Create a holder to contain inflated xml file elements ***********/
public static class ViewHolder{
public TextView text;
}
/*********** Depends upon data size called for each row , Create each ListView row ***********/
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
ViewHolder holder;
if(convertView==null){
/********** Inflate tabitem.xml file for each row ( Defined below ) ************/
vi = inflater.inflate(R.layout.articleitems, null);
/******** View Holder Object to contain tabitem.xml file elements ************/
holder=new ViewHolder();
holder.text=(TextView)vi.findViewById(R.id.atextView1);
Typeface typeface = Typeface.createFromAsset(holder.text.getContext().getAssets(),
"fonts/B YEKAN.TTF");
holder.text.setTypeface(typeface);
/************ Set holder with LayoutInflater ************/
vi.setTag(holder);
}
else
holder=(ViewHolder)vi.getTag();
if(data.size()<=0)
{
holder.text.setText("No Data");
}
else
{
/***** Get each Model object from Arraylist ********/
tempValues=null;
tempValues = (ArticlesModel) data.get(position);
/************ Set Model values in Holder elements ***********/
holder.text.setText(tempValues.getArticleName());
}
return vi;
}
#Override
public void onClick(View v) {
Log.v("CustomAdapter", "=====Row button clicked");
}
/********* Called when Item click in ListView ************/
private class OnItemClickListener implements OnClickListener{
private int mPosition;
OnItemClickListener(int position){
mPosition = position;
}
#Override
public void onClick(View arg0) {
MainActivity sct = (MainActivity)activity;
sct.articleItemClick(mPosition);
}
}
}
and of course i have two xml layout for my items style:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/cLinearLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:gravity="right"
android:orientation="vertical"
android:paddingBottom="10dp" >
<LinearLayout
android:id="#+id/cLinearLayout2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:gravity="right" >
<TextView
android:id="#+id/ctextView1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical|center_horizontal"
android:paddingRight="10dp"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#215e76"
android:textSize="20sp" />
<ImageView
android:id="#+id/cimageView2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:maxHeight="20dp"
android:maxWidth="20dp"
android:padding="5dp"
android:src="#drawable/ic_launcher" />
<ImageView
android:id="#+id/cimageView1"
android:layout_width="10dp"
android:layout_height="match_parent"
android:background="#ffc20e" />
</LinearLayout>
</LinearLayout>
and another is
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/aLinearLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:gravity="right"
android:orientation="vertical"
android:paddingBottom="10dp" >
<LinearLayout
android:id="#+id/aLinearLayout3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:gravity="right" >
<TextView
android:id="#+id/atextView1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical|center_horizontal"
android:paddingRight="10dp"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#215e76"
android:textSize="20sp" />
<ImageView
android:id="#+id/aimageView1"
android:layout_width="10dp"
android:layout_height="match_parent"
android:background="#ffc20e" />
</LinearLayout>
</LinearLayout>
now when i run program
fragment that fill with customadapter work very good
but fragment that filled by articlesadapter have below error
java.lang.ClassCastException: ir.monocode.az.ArticlesModel cannot be cast to ir.monocode.az.CatsModel
how i must solve my problem?
can you help me please?
thank you
You can solve with polymorphism. Replace the failing declaration (the one your cast error comes from) with the Interface BaseAdapter
Something like this (your relevant code wasn't posted, so this is just a guess)
CatsModel it = retrieveMyCustomAdapter();
becomes
BaseAdapter it = retrieveMyCustomAdapter();
A more formal approach would be to declare an abstract class extending BaseAdapter, and make both CatsModel and ArticlesModel inherit from this new class.
Related
I want to create a ListView in a Fragment for chats just like WhatsApp but the adapter is showing null. Below is my code :
ChatsFragment.java
package com.houssup.userchat;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import java.util.ArrayList;
public class ChatsFragment extends Fragment {
ListView list;
CustomChatAdapter adapter;
public ChatsFragment chatsFragment = null;
public ArrayList<ListModel> CustomListViewValuesArr = new ArrayList<ListModel>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.customrow_chat, container, false);
ListView lv= ( ListView )view.findViewById( R.id.list ); // List defined in XML ( See Below )
/**************** Create Custom Adapter *********/
setListData();
adapter=new CustomChatAdapter( getContext(), CustomListViewValuesArr);
lv.setAdapter(adapter);
return view;
}
public void setListData()
{
for (int i = 0; i < 11; i++) {
final ListModel sched = new ListModel();
/******* Firstly take data in model object ******/
sched.setName("Swapnil"+i);
sched.setDesignation("Interior Designer"+i);
/******** Take Model Object in ArrayList **********/
CustomListViewValuesArr.add( sched );
}
}
}
CustomChatAdapter.java
package com.houssup.userchat;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.content.res.Resources;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import de.hdodenhof.circleimageview.CircleImageView;
/**
* Created by hp on 01-06-2016.
*/
public class CustomChatAdapter extends BaseAdapter{
private Context context;
private ArrayList data;
private static LayoutInflater inflater=null;
ListModel tempValues=null;
int i=0;
/************* CustomChatAdapter Constructor *****************/
public CustomChatAdapter(Context context, ArrayList d) {
/********** Take passed values **********/
this.context=context;
data=d;
/*********** Layout inflator to call external xml layout () ***********/
inflater = ( LayoutInflater )context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
/******** What is the size of Passed Arraylist Size ************/
public int getCount() {
if(data.size()<=0)
return 1;
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
/********* Create a holder Class to contain inflated xml file elements *********/
public static class ViewHolder{
public TextView name;
public TextView designation;
public CircleImageView image;
}
/****** Depends upon data size called for each row , Create each ListView row *****/
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
ViewHolder holder;
if(convertView==null){
/****** Inflate tabitem.xml file for each row ( Defined below ) *******/
vi = inflater.inflate(R.layout.customrow_chat, null);
/****** View Holder Object to contain tabitem.xml file elements ******/
holder = new ViewHolder();
holder.name = (TextView) vi.findViewById(R.id.name);
holder.designation=(TextView)vi.findViewById(R.id.designation);
holder.image= (CircleImageView) vi.findViewById(R.id.image);
/************ Set holder with LayoutInflater ************/
vi.setTag( holder );
}
else
holder=(ViewHolder)vi.getTag();
if(data.size()<=0)
{
holder.name.setText("No Data");
}
else
{
/***** Get each Model object from Arraylist ********/
tempValues=null;
tempValues = ( ListModel ) data.get( position );
/************ Set Model values in Holder elements ***********/
holder.name.setText( tempValues.getName() );
holder.designation.setText( tempValues.getDesignation() );
holder.image.setImageResource(R.drawable.circuladp);
/******** Set Item Click Listner for LayoutInflater for each row *******/
/* vi.setOnClickListener(new OnItemClickListener( position ));*/
}
return vi;
}
/* #Override
public void onClick(View v) {
Log.v("CustomChatAdapter", "=====Row button clicked=====");
}*/
/********* Called when Item click in ListView ************/
/* private class OnItemClickListener implements View.OnClickListener {
private int mPosition;
OnItemClickListener(int position){
mPosition = position;
}
*//*#Override
public void onClick(View arg0) {
CustomListViewAndroidExample sct = (CustomListViewAndroidExample)activity;
*//**//**** Call onItemClick Method inside CustomListViewAndroidExample Class ( See Below )****//**//*
sct.onItemClick(mPosition);
}*/
}
fragment_chats.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.houssup.userchat.ChatsFragment">
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</FrameLayout>
customrow_chat.xml
<?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="wrap_content"
android:orientation="horizontal">
<de.hdodenhof.circleimageview.CircleImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/profile_image"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="#drawable/circuladp"
app:civ_border_width="2dp"
app:civ_border_color="#FF000000"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="vertical">
<TextView
android:id="#+id/name"
android:layout_below="#id/title"
android:text="Yashvant Rai Bacchhan"
android:layout_marginLeft="50dp"
android:textSize="18dp"
android:textColor="#000000"
android:layout_marginTop="10dp"
android:textStyle="bold"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/designation"
android:layout_width="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginTop="6dp"
android:layout_marginLeft="55dp"
android:textSize="14dp"
android:layout_height="wrap_content"
android:text="Designer"/>
</LinearLayout>
</LinearLayout>
This fragment is in a TabActivity.I don't know why it is showing null. Any help will be appreciated !!
The code shows that you inflating the fragment view for the layout 'R.layout.customrow_chat' but the layout name is 'fragment_chats.xml'. Typo?
See you code. you convertView is always null.
change it:
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView==null){
/****** Inflate tabitem.xml file for each row ( Defined below ) *******/
convertView = inflater.inflate(R.layout.customrow_chat, null);
/****** View Holder Object to contain tabitem.xml file elements ******/
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.designation=(TextView)convertView.findViewById(R.id.designation);
holder.image= (CircleImageView) convertView.findViewById(R.id.image);
/************ Set holder with LayoutInflater ************/
convertView.setTag( holder );
}
else
holder=(ViewHolder)convertView.getTag();
if(data.size()<=0)
{
holder.name.setText("No Data");
}
else
{
/***** Get each Model object from Arraylist ********/
tempValues=null;
tempValues = ( ListModel ) data.get( position );
/************ Set Model values in Holder elements ***********/
holder.name.setText( tempValues.getName() );
holder.designation.setText( tempValues.getDesignation() );
holder.image.setImageResource(R.drawable.circuladp);
/******** Set Item Click Listner for LayoutInflater for each row *******/
/* vi.setOnClickListener(new OnItemClickListener( position ));*/
}
return convertView;
}
I am new to android and facing one very comman problem of listview i googled alot but did'nt found anything usefull for my case.Hope you people show me the right direction.Whenever I am changing my image from "plus" to "tick" on click my last item image also got automatically changed on scroll.
My list_comapare_product XMl :-
<?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:background="#color/white_color"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:background="#color/white_color"
android:gravity="center_vertical" >
<ImageView
android:id="#+id/img_product"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="#drawable/crane" />
<com.mss.skyjack.custom.views.SkyjackCustomTextview
android:id="#+id/tv_product_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:gravity="center"
android:text="test"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="#+id/img_plus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="#drawable/plus" />
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:background="#color/black_color" />
</LinearLayout>
Here is my Adapter :-
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class ComapreProductSelectionAdapter extends BaseAdapter {
Activity activity;
List<SelectorTest> listSelector;
private LayoutInflater mLayoutInflater;
public ComapreProductSelectionAdapter(Activity activity,
List<SelectorTest> listSelector) {
this.activity = activity;
this.listSelector = listSelector;
mLayoutInflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return listSelector.size();
}
#Override
public SelectorTest getItem(int position) {
return listSelector.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
final int i = position;
final SelectorTest listItem = listSelector.get(position);
if (convertView == null) {
convertView = mLayoutInflater.inflate(
R.layout.list_comapare_product, parent, false);
viewHolder = new ViewHolder();
viewHolder.tvProductName = (TextView) convertView
.findViewById(R.id.tv_product_name);
viewHolder.imgProduct = (ImageView) convertView
.findViewById(R.id.img_product);
viewHolder.imgadd = (ImageView) convertView
.findViewById(R.id.img_plus);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.imgadd.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (viewHolder.imgadd.getDrawable().getConstantState() == activity
.getResources().getDrawable(R.drawable.plus)
.getConstantState()) {
viewHolder.imgadd.setImageResource(R.drawable.tick);
} else {
viewHolder.imgadd.setImageResource(R.drawable.plus);
}
}
});
return convertView;
}
static class ViewHolder {
TextView tvProductName;
ImageView imgProduct, imgadd;
View viewRightLine;
}
}
Thanks.
You need to keep track of which items have been "ticked". I copied your adapter and made necessary changes. You can just copy-paste the code and it should work.
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class ComapreProductSelectionAdapter extends BaseAdapter {
Activity activity;
List<SelectorTest> listSelector;
private LayoutInflater mLayoutInflater;
private ArrayList<Integer> tickedItems = new ArrayList<Integer>();
public ComapreProductSelectionAdapter(Activity activity,
List<SelectorTest> listSelector) {
this.activity = activity;
this.listSelector = listSelector;
mLayoutInflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return listSelector.size();
}
#Override
public SelectorTest getItem(int position) {
return listSelector.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
final int i = position;
final SelectorTest listItem = listSelector.get(position);
if (convertView == null) {
convertView = mLayoutInflater.inflate(
R.layout.list_comapare_product, parent, false);
viewHolder = new ViewHolder();
viewHolder.tvProductName = (TextView) convertView
.findViewById(R.id.tv_product_name);
viewHolder.imgProduct = (ImageView) convertView
.findViewById(R.id.img_product);
viewHolder.imgadd = (ImageView) convertView
.findViewById(R.id.img_plus);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.imgadd.setTag(position);
viewHolder.imgadd.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(tickedItems.contains((Integer)v.getTag()) {
//Already ticked, set to plus
viewHolder.imgadd.setImageDrawable(activity.getResources().getDrawable(R.drawable.plus));
tickedItems.remove((Integer)v.getTag());
} else {
tickedItems.add((Integer)v.getTag());
viewHolder.imgadd.setImageDrawable(activity.getResources().getDrawable(R.drawable.tick));
}
}
});
if(tickedItems.contains(position))
viewHolder.imgadd.setImageDrawable(activity.getResources().getDrawable(R.drawable.tick));
else
viewHolder.imgadd.setImageDrawable(activity.getResources().getDrawable(R.drawable.plus));
return convertView;
}
static class ViewHolder {
TextView tvProductName;
ImageView imgProduct, imgadd;
View viewRightLine;
}
}
As an extra, don't use ImageView.setImageResource() as it is inefficient.
Quote from Android docs about ImageView.setImageReource()
This does Bitmap reading and decoding on the UI thread, which can cause a latency hiccup. If that's a concern, consider using setImageDrawable(android.graphics.drawable.Drawable) or setImageBitmap(android.graphics.Bitmap) and BitmapFactory instead.
I am not able to set textview's setText property inside getView() method of Custom Adapter.
I already tried below solutions but it does not work for me :
Solution One
Solution Two
Solution Three
Listview.xml file :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/imgLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:divider="#null"
android:dividerHeight="5dp"
android:scrollbars="none" />
</RelativeLayout>
Below is my keep_resing xml file :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/customRowLayout"
android:layout_width="fill_parent"
android:layout_height="60dp"
android:layout_marginTop="20dp"
android:orientation="horizontal" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:orientation="vertical" >
<ImageButton
android:id="#+id/Btn"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="10dp"
android:background="#drawable/thumb_down_disabled" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="#string/resing"
android:textColor="#357EC7"
android:textSize="10sp" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:orientation="vertical" >
<TextView
android:id="#+id/lyricsTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<RelativeLayout
android:id="#+id/parentLayout"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="5dp"
android:background="#drawable/playing_view"
android:orientation="horizontal" >
<TextView
android:id="#+id/helloTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginLeft="5dp"
android:singleLine="true"
android:text="Hello"
android:textColor="#357EC7"
android:textSize="14sp" />
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="5dp"
android:background="#drawable/volume" />
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:orientation="vertical" >
<ImageButton
android:id="#+id/keepBtn"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginRight="10dp"
android:background="#drawable/thumb_up_disabled" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="#string/keep"
android:textColor="#357EC7"
android:textSize="10sp" />
</LinearLayout>
</RelativeLayout>
Below is my adapter code :
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.simpleframework.xml.stream.Position;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Handler;
import android.os.PowerManager;
import android.sax.StartElementListener;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
public class KeepReSingAdapter extends BaseAdapter implements OnClickListener {
/*********** Declare Used Variables *********/
private Activity activity;
private ArrayList data;
private static LayoutInflater inflater = null;
public Resources res;
SongCue tempValues = null;
int i = 0;
private ArrayList<SongCue> songCue;
private int cueIndex = 0;
private String selectedSongId;
private MediaPlayer mMediaPlayer;
ViewHolder holder;
View vi;
boolean right_button_flag, left_button_flag;
SessionManager session;
// int left_button_flag;
/************* CustomAdapter Constructor *****************/
public KeepReSingAdapter(Activity a, ArrayList d, Resources resLocal) {
/********** Take passed values **********/
activity = a;
data = d;
res = resLocal;
/*********** Layout inflator to call external xml layout () ***********/
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
selectedSongId = SessionManager.getInstance(
activity.getApplicationContext()).getString(
AppConstants.SONG_ID);
right_button_flag = false;
left_button_flag = false;
// Session class instance
session = new SessionManager(activity.getApplicationContext());
}
/******** What is the size of Passed Arraylist Size ************/
public int getCount() {
if (data.size() <= 0)
return 1;
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
/********* Create a holder Class to contain inflated xml file elements *********/
public static class ViewHolder {
public TextView lyricsTxt, helloTxt;
// public TextView text1;
public ImageButton leftBtn, rightBtn;
public RelativeLayout parentLayout;
public LinearLayout rowLayout;
// public TextView textWide;
// ImageView image;
}
/****** Depends upon data size called for each row , Create each ListView row *****/
public View getView(final int position, View convertView, ViewGroup parent) {
vi = convertView;
if (convertView == null) {
vi = inflater.inflate(R.layout.keep_resing, null);
holder = new ViewHolder();
holder.lyricsTxt = (TextView) vi.findViewById(R.id.lyricsTxt);
holder.helloTxt = (TextView) vi.findViewById(R.id.helloTxt);
holder.leftBtn = (ImageButton) vi.findViewById(R.id.reSingBtn);
holder.rightBtn = (ImageButton) vi.findViewById(R.id.keepBtn);
holder.parentLayout = (RelativeLayout) vi
.findViewById(R.id.parentLayout);
holder.rowLayout = (LinearLayout) vi
.findViewById(R.id.customRowLayout);
vi.setTag(holder);
} else {
holder = (ViewHolder) vi.getTag();
}
if (data.size() <= 0) {
} else {
/***** Get each Model object from Arraylist ********/
tempValues = null;
tempValues = (SongCue) data.get(position);
holder.lyricsTxt.setText(tempValues.getLyric());
List<Song> AllSong = SplashScreen_Activity.songs;
if (selectedSongId != null) {
for (Song tempsong : AllSong) {
if (tempsong.songId.equals(selectedSongId)) {
songCue = (ArrayList<SongCue>) tempsong.songCues.songCue;
}
}
} else {
}
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(activity.getApplicationContext(),
" " + position, Toast.LENGTH_SHORT).show();
holder.helloTxt.setText("Test");
Toast.makeText(activity.getApplicationContext(),
holder.helloTxt.getText().toString(),
Toast.LENGTH_LONG).show();
}
});
}
vi.setOnClickListener(new OnItemClickListener(position));
return vi;
}
#Override
public void onClick(View v) {
Log.v("CustomAdapter", "=====Row button clicked=====");
}
/********* Called when Item click in ListView ************/
private class OnItemClickListener implements OnClickListener {
private int mPosition;
OnItemClickListener(int position) {
mPosition = position;
}
#Override
public void onClick(View arg0) {
}
}
}
Problem is, I am not able to change the text view text to "Test".
Note : If I see the value in Toast by doing "holder.helloTxt.getText().toString()" it shows me "Test".
I don't know why this problem is arising.Any help will be highly appreciated.
Thanks
Finally I got the solution to my question and guess what it was a minor updation in the code.
I updated my code to :
final ViewHolder holder;
inside getView() of CustomAdapter instead of declaring it globally.
Once again, thanking you all for your answers.
It helped me to look into my code in detail.
Try this hope this helps
vi = convertView;
if (vi == null) {
vi = inflater.inflate(R.layout.xmlfile, null);
holder = new ViewHolder();
holder.helloTxt= (TextView) vi.findViewById(R.id.hearTxt);
holder.parentLayout= (RelativeLayout) vi
.findViewById(R.id.parentLayout);
vi.setTag(holder);
}else
holder=(ViewHolder)vi.getTag();
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(activity.getApplicationContext(),
" " + position, Toast.LENGTH_SHORT).show();
holder.helloTxt.setText("Test");// not required
// just change the value of text in your list(which you are passing to the adapter) at corresponding position and then notify the list
notifyDataSetChanged();
Toast.makeText(activity.getApplicationContext(),
holder.helloTxt.getText().toString(),
Toast.LENGTH_LONG).show();
}
});
return vi;
It will display the text "test" but when you scroll, it will again changed to its original value so you have to change the value in the list also which you are sending to the adapter
Also in your case the problem is, when you update the text of your TextView, it gets updated for the time being that's why you are getting the TextView text in your Toast. But in order to show the updated text in ListView, you have to notify the List. But when you do so, your TextView resets to original value. So all you have to do is to take a global String variable and intialise that to your initial value whatever you want like this
private String yourText="initial text"
and in getView() set your TextView text to this variable like this
holder.helloTxt.setText(yourText);
and when you click your parentLayout,just assign, this string the value you want and notify the list
yourText="test";
notifyDataSetChanged();
and this will do the trick. But remember this works only when you have single row, if you have multiple rows you have to take a String array.
Do you perform a holder = vi.getTag(); in case the convertView not is null?
This is necessary when a view is already created to reinitialise it in the state it was.
Problem is, I am not able to change the text view text to "Test".
you are doing it wrong. Let's say your adapter is made of String. What I would have expected, is
if (convertView == null) {
// inflate stuff
// create older
// set the older in the converView's tag
} else {
// retriewholder
}
// here you set the String in the holder at position:
String tmpString = getItem(position);
holder.helloTxt.setText(tmpString);
holder.parentLayout.setTag(position);
Inside the onClick, you can retrieve the position trough the tag object, and update the String in the dataset and call notifyDataSetChanged
Your problem is you didnot touch the parent layout. Make sure that your finger can touch the parentLayout, you can add padding for it. Or you can try
holder.helloTxt.setOnClickListener(...)
instead of parentLayout.
I've seen a lot of ways but for me the simple way is pass component view to adapter. Then you can change you need. See an example below:
Link
I want the list view and tab bar both at the same time and my code is below:
Please check my Main Activity and Custom Adapter and tell me what changes I need to do.
Because list is working but tabs are not being displayed.
Two XML files I have included.
1.tab_bar
2.final_tab_item
Please let me know where I am going wrong...
MainActivity.java
package com.example.tabwithlist;
import java.util.ArrayList;
import com.example.customlist.CustomAdapter;
import com.example.customlist.ListModel;
import android.app.TabActivity;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;
import android.widget.TabHost;
import android.widget.TabHost.OnTabChangeListener;
public class MainActivity extends TabActivity implements OnTabChangeListener
{
ListView list;
CustomAdapter adapter;
public ArrayList<ListModel> CustomListViewValuesArr = new ArrayList<ListModel>();
/** Called when the activity is first created. */
TabHost tabHost;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tab_bar);
// setContentView(R.layout.custom_list_view);
setListData();
Resources res =getResources();
list=(ListView)findViewById(R.id.listnew);
//**************** Create Custom Adapter *********//*
adapter=new CustomAdapter(this, CustomListViewValuesArr,res);
list.setAdapter(adapter);
for (int i = 0; i < 11; i++) {
final ListModel sched = new ListModel();
//******* Firstly take data in model object ******//*
sched.setCompanyName("Company "+i);
sched.setImage("image"+i);
sched.setUrl("http:\\\\www."+i+".com");
//******** Take Model Object in ArrayList **********//*
CustomListViewValuesArr.add(sched);
}
// Get TabHost Refference
tabHost = getTabHost();
// Set TabChangeListener called when tab changed
tabHost.setOnTabChangedListener(this);
TabHost.TabSpec spec;
Intent intent;
//************* TAB1 ************//*
// Create Intents to launch an Activity for the tab (to be reused)
intent = new Intent().setClass(this, Tab1.class);
spec = tabHost.newTabSpec("First").setIndicator("")
.setContent(intent);
//Add intent to tab
tabHost.addTab(spec);
//************* TAB2 ************//*
intent = new Intent().setClass(this, Tab2.class);
spec = tabHost.newTabSpec("Second").setIndicator("")
.setContent(intent);
tabHost.addTab(spec);
/************* TAB3 ************/
intent = new Intent().setClass(this, Tab3.class);
spec = tabHost.newTabSpec("Third").setIndicator("")
.setContent(intent);
tabHost.addTab(spec);
// Set drawable images to tab
tabHost.getTabWidget().getChildAt(1).setBackgroundResource(R.drawable.tab2);
tabHost.getTabWidget().getChildAt(2).setBackgroundResource(R.drawable.tab3);
// Set Tab1 as Default tab and change image
tabHost.getTabWidget().setCurrentTab(0);
tabHost.getTabWidget().getChildAt(0).setBackgroundResource(R.drawable.tab1_over);
}
private void setListData() {
for (int i = 0; i < 11; i++) {
final ListModel sched = new ListModel();
/******* Firstly take data in model object ******/
sched.setCompanyName("Company "+i);
sched.setImage("image"+i);
sched.setUrl("http:\\\\www."+i+".com");
/******** Take Model Object in ArrayList **********/
CustomListViewValuesArr.add(sched);
}
}
#Override
public void onTabChanged(String tabId) {
/************ Called when tab changed *************/
//********* Check current selected tab and change according images *******/
for(int i=0;i<tabHost.getTabWidget().getChildCount();i++)
{
if(i==0)
tabHost.getTabWidget().getChildAt(i).setBackgroundResource(R.drawable.tab1);
else if(i==1)
tabHost.getTabWidget().getChildAt(i).setBackgroundResource(R.drawable.tab2);
else if(i==2)
tabHost.getTabWidget().getChildAt(i).setBackgroundResource(R.drawable.tab3);
}
Log.i("tabs", "CurrentTab: "+tabHost.getCurrentTab());
if(tabHost.getCurrentTab()==0)
tabHost.getTabWidget().getChildAt(tabHost.getCurrentTab()).setBackgroundResource(R.drawable.tab1_over);
else if(tabHost.getCurrentTab()==1)
tabHost.getTabWidget().getChildAt(tabHost.getCurrentTab()).setBackgroundResource(R.drawable.tab2_over);
else if(tabHost.getCurrentTab()==2)
tabHost.getTabWidget().getChildAt(tabHost.getCurrentTab()).setBackgroundResource(R.drawable.tab3_over);
}
}
CustomAdapter.java(Here I am inflating my final_tab_item.xml file which displays how list view will look like.)
package com.example.customlist;
import java.util.ArrayList;
import android.R;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.view.LayoutInflater;
//import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class CustomAdapter extends BaseAdapter {
/*********** Declare Used Variables *********/
private Activity activity;
private ArrayList data;
private static LayoutInflater inflater=null;
public Resources res;
ListModel tempValues=null;
int i=0;
/************* CustomAdapter Constructor *****************/
public CustomAdapter(Activity a, ArrayList d,Resources resLocal) {
/********** Take passed values **********/
activity = a;
data=d;
res = resLocal;
/*********** Layout inflator to call external xml layout () **********************/
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
/******** What is the size of Passed Arraylist Size ************/
public int getCount() {
if(data.size()<=0)
return 1;
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
/********* Create a holder to contain inflated xml file elements ***********/
public static class ViewHolder{
public TextView text;
public TextView text1;
public TextView textWide;
public ImageView image;
}
/*********** Depends upon data size called for each row , Create each ListView row ***********/
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
ViewHolder holder;
if(convertView==null){
/********** Inflate tabitem.xml file for each row ( Defined below ) ************/
//vi = inflater.inflate(R.layout., null);
vi=inflater.inflate(com.example.tabwithlist.R.layout.final_tab_item,null);
/******** View Holder Object to contain tabitem.xml file elements ************/
holder=new ViewHolder();
holder.text=(TextView)vi.findViewById(com.example.tabwithlist.R.id.text);
holder.text1=(TextView)vi.findViewById(com.example.tabwithlist.R.id.text1);
holder.image=(ImageView)vi.findViewById(com.example.tabwithlist.R.id.image);
/************ Set holder with LayoutInflater ************/
vi.setTag(holder);
}
else
holder=(ViewHolder)vi.getTag();
if(data.size()<=0)
{
holder.text.setText("No Data");
}
else
{
/***** Get each Model object from Arraylist ********/
tempValues=null;
tempValues = (ListModel) data.get(position);
/************ Set Model values in Holder elements ***********/
holder.text.setText(tempValues.getCompanyName());
holder.text1.setText(tempValues.getUrl());
holder.image.setImageResource(res.getIdentifier("com.example.tabwithlist:drawable/"+tempValues.getImage(),null,null));
/******** Set Item Click Listner for LayoutInflater for each row ***********/
// vi.setOnClickListener(new OnItemClickListener(position));
}
return vi;
}
}
tab_bar.xml(In this file I am declaring list view and tab bar)
<?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">
<TabHost
android:id="#android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RelativeLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"/>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</RelativeLayout>
</TabHost>
<ListView
android:id="#+id/listnew"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</RelativeLayout>
Ur MainActivity loads the tabs only, put our listview code in first tab (Tab1.class)
Changes:
tab_bar.xml with
<TabHost
android:id="#android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RelativeLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"/>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</RelativeLayout>
</TabHost>
remove all the listview code from ur MainActivity.
Create Tab1, Tab2 and Tab3 activities.
Create new xml add
<ListView
android:id="#+id/listnew"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
Move all the listview code to Tab1.java
I'm trying to change the row color of my listView in customAdapter. There's an array of integer that include 0 and 1, I'm trying to read from the array and change the color of rows like this:
0 = white
1 = yellow
but it shows a yellow color in all rows.
This is my CustomAdapter:
package com.example.test;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class CustomAdapter extends ArrayAdapter<RowItem> {
ArrayList<Integer> test;
Context context;
public CustomAdapter(Context context, int resourceId, List<RowItem> items) {
super(context, resourceId, items);
this.context = context;
}
/* private view holder class */
private class ViewHolder {
ImageView imageView;
TextView txtTitle;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
RowItem rowItem = getItem(position);
SqliteHelper checkFav = new SqliteHelper(context);
checkFav.open();
test = checkFav.getFavForList();
checkFav.close();
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.row_layout, null);
holder = new ViewHolder();
holder.txtTitle = (TextView) convertView.findViewById(R.id.pTxt);
holder.imageView = (ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);
} else
holder = (ViewHolder) convertView.getTag();
int color0 = Color.YELLOW;
int colorDefault = Color.WHITE;
switch (test.get(position)){
case 0:
convertView.setBackgroundColor(colorDefault);
break;
case 1:
convertView.setBackgroundColor(color0);
}
holder.txtTitle.setText(rowItem.getTitle());
holder.imageView.setImageResource(rowItem.getImageId());
return convertView;
}
}
And this is my row_layout.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="horizontal" >
<ImageView
android:id="#+id/icon"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginBottom="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
android:src="#drawable/active_icon" />
<TextView
android:id="#+id/pTxt"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textSize="20sp"
android:gravity="right"/>
</LinearLayout>
Thanks in advance.
getView() is called for each row in a list so you should not loop over all items in test but only handle the one denoted by position and you should do that after (not in) the if (convertView == null) block.
Edit:
getView() should do the following things:
Check if convertView isn't null (if it is, create a new View as you did)
Check if convertView is of the right type (this only matters if more than one kind of View is used in the list which is not the case here). If the type is wrong, create a new View.
Now we have a valid View for the list row.
Retrieve the data which affects how to display this row. In your case this would be the result of test.get(position). The position is the number of the requested row (starting with 0 at the top of the ListView).
Adjust the View according to your data (you did this in the for-loop but you should do it only once for the requested entry at position).
Return the View
In more complex situations you may have to do the third step before the second but not here.
Fast solution (not very nice code, but works):
#Override
public int getItem(int position){
return test.get(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
int color0 = ....
int color1 = ....
int colorDefault = ...
switch (test.get(position)) {
case 0:
convretview.setBackgroundColor(color0);
break;
case 1:
convretview.setBackgroundColor(color1);
break;
default:
convretview.setBackgroundColor(colorDefault);
}
...
}