Android Baseadapter fixed blankfields - android

I have got a problem with my BaseAdapter. I am using a Gridview to show my content. And i need to add some blankfield.
But if i scroll up and down the blankfields move randomly.
My Question is: How can i make them stay at the right position?
public class GridviewAdapter extends BaseAdapter {
private ArrayList<String> sign;
private ArrayList<String> roman;
private ArrayList<String> check;
private Activity activity;
private int minusValue=0;
private boolean fulllist;
public GridviewAdapter(Activity activity, ArrayList<String> sign,ArrayList<String> roman,ArrayList<String> check,boolean fulllist) {
super();
this.activity=activity;
this.sign=sign;
this.roman=roman;
this.check=check;
this.fulllist=fulllist;
}
#Override
public int getCount() {
if(fulllist)
{
return sign.size()+5;
}
else
{
return sign.size();
}
}
public void updateList(ArrayList<String> newcheck) {
check.clear();
check.addAll(newcheck);
this.notifyDataSetChanged();
}
#Override
public Object getItem(int position) {
return sign.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public static class ViewHolder
{
public TextView signv;
public TextView romanv;
public TextView checkv;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder view= new ViewHolder();
LayoutInflater inflator = activity.getLayoutInflater();
if (convertView == null) {
view = new ViewHolder();
convertView = inflator.inflate(R.layout.gridblock, null);
view.signv = (TextView) convertView.findViewById(R.id.sign);
view.checkv = (TextView) convertView.findViewById(R.id.check);
view.romanv = (TextView) convertView.findViewById(R.id.roman);
convertView.setTag(view);
} else {
view = (ViewHolder) convertView.getTag();
}
if(position==36) {
convertView.setVisibility(View.GONE);
convertView.setClickable(false);
convertView.setEnabled(false);
minusValue=minusValue-1;
}
else if(position==38) {
convertView.setVisibility(View.GONE);
convertView.setClickable(false);
convertView.setEnabled(false);
minusValue=minusValue-1;
}
else if(position==46) {
convertView.setVisibility(View.GONE);
convertView.setClickable(false);
convertView.setEnabled(false);
minusValue=minusValue-1;
}
else if(position==47) {
convertView.setVisibility(View.GONE);
convertView.setClickable(false);
convertView.setEnabled(false);
minusValue=minusValue-1;
}
else if(position==48) {
convertView.setVisibility(View.GONE);
convertView.setClickable(false);
convertView.setEnabled(false);
minusValue=minusValue-1;
}
else
{
view.signv.setText(sign.get(0));
view.checkv.setText(check.get(0));
if( view.checkv.getText().equals("✘"))
{
view.checkv.setTextColor(Color.RED);
}
else
{
view.checkv.setTextColor(Color.GREEN);
}
view.romanv.setText(roman.get(0));
}
return convertView;
}

In the else clause, when updating all the ViewHolder fields, you need to undo the invisibility applied for the blank positions. Eg:
convertView.setVisibility(View.VISIBLE);
convertView.setClickable(true);
convertView.setEnabled(true);
This is because recycled views are not guaranteed to be the same position as when they were initially inflated. Meaning the view used for position 47 may be reused for position 2.
I'm not sure what you are doing with the minusValue but you may need to adjust that as well. Keep in mind, getView() can and will be called 3-4 times per position number. Just an FYI when using that variable.

Related

Android getView() in BaseAdapter not called (but getCount() is called)

There no errors but the ListView is empty. I have implemented getCount() which returns right number of items in my ArrayList. And the ListView is visibility。
I had call setListAdapter on the ListView,and the xml is match_parent.
This is my Fragment.
mNewsList = infoBean.getNews();
if (mNewsList != null) {
mNewsAdapter = new NewsAdapter();
mListView.setAdapter(mNewsAdapter);
mNewsAdapter.notifyDataSetChanged();
}
} else {//load more
List<HomeBean.NewsBean> news = infoBean.getNews();
if (mNewsList != null) {
mNewsList.addAll(news);
mNewsAdapter.notifyDataSetChanged();
}
This is my Adapter:
private class NewsAdapter extends BaseAdapter {
#Override
public int getCount() {
return mNewsList.size();
}
#Override
public HomeBean.NewsBean getItem(int position) {
return mNewsList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = View.inflate(MyApplication.getmContext(), R.layout.item_list, null);
holder = new ViewHolder();
holder.ivIcon = convertView.findViewById(R.id.iv_item);
holder.tvTitle = convertView.findViewById(R.id.tv_item_list_title);
holder.content = convertView.findViewById(R.id.tv_item_list_content);
holder.tvTime = convertView.findViewById(R.id.tv_time);
holder.author = convertView.findViewById(R.id.tv_author);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.tvTitle.setText(getItem(position).getTitle());
holder.content.setText(getItem(position).getContent());
SimpleDateFormat dataFormat = new SimpleDateFormat("yyyy-MM-dd");
String itemTime = dataFormat.format(getItem(position).getCreate_at() * 1000);
holder.tvTime.setText(itemTime);
holder.author.setText(getItem(position).getSection_name());
if (getItem(position).getCover_pic().startsWith("http:")) {
picUrl = getItem(position).getCover_pic();
} else {
picUrl = RBConstants.SERVER_PIC + getItem(position).getCover_pic();
}
HttpLoader.getInstance(MyApplication.getmContext()).display(holder.ivIcon, picUrl);
return convertView;
}
}
This is my holder.
class ViewHolder {
public ImageView ivIcon;
public TextView tvTitle;
public TextView tvTime;
public TextView content;
public TextView author;
}
this is because mListView.setAdapter(mNewsAdapter); is never executed and of cource there is no need to call mNewsAdapter.notifyDataSetChanged(); immediatelly after calling mListView.setAdapter(mNewsAdapter);
ListView is old, please switch to RecyclerView.

How to change row view in listview when clicking on item

Is it possible to change row view when I'm clicking on it? For example I have listView with rows where some short information shown, and when after clicking on row detailed view will show instead of old row.
I tried to use addView in my listView, but "listview addView(View, int) is not supported in AdapterView" error appeared.
try something like that:
public class MyAdapter extends BaseAdapter {
private Context mContext;
private List<UserPojo> mList;
public MyAdapter(Context context, List<UserPojo> users) {
this.mContext = context;
this.mList = users;
}
#Override
public int getCount() {
return mList.size();
}
#Override
public UserPojo 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) {
final UserPojo user = mList.get(position);
final ViewHolder holder;
if (convertView == null) {
convertView = View.inflate(mContext, R.layout.item_ad, null);
holder = new ViewHolder();
holder.pic = (CircleImageView) convertView.findViewById(R.id.profile_imageView);
holder.name = (TextView) convertView.findViewById(R.id.name_textView);
convertView.setTag(holder);
} else{
holder = (ViewHolder) convertView.getTag();
}
if (user.isClicked) {
holder.pic.setVisibility(View.VISIBLE);
holder.name.setVisibility(View.GONE);
} else {
holder.pic.setVisibility(View.GONE);
holder.name.setVisibility(View.VISIBLE);
}
holder.name.setText("text");
holder.name.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
user.setClicked(true);
notifyDataSetChanged();
}
});
return convertView;
}
private static class ViewHolder {
CircleImageView pic;
TextView name;
}
}

notifyDatasetChanged is not working inside the getView() method for Custom Adapter In Android

I am basically trying hide and show a text in the list row when I am clicking a button in the list row. I have added the onClick() for the button inside getView() method and then calling the notifyDataSetChanged(). But it is not working. No change in the text visibility. Here is my custom Adapter code:
public class ListAdapter extends BaseAdapter {
private Context context;
private List<String> mListQuestion = null;
private List<String> mListAnswer = null;
ViewHolder holder = null;
boolean flag = false;
public ListAdapter(Context context, List<String> question, List<String> answer ) {
this.mListQuestion = question;
this.mListAnswer = answer;
this.context = context;
}
#Override
public Object getItem(int position)
{
return mListQuestion.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getCount() {
return mListQuestion.size();
}
#Override
#SuppressWarnings("deprecation")
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null)
{
LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.list_faq_item, null);
holder = new ViewHolder();
holder.tvQuestion = (TextView) convertView.findViewById(R.id.text);
holder.tvAns = (TextView) convertView.findViewById(R.id.anstext);
holder.ivArrow = (Button)convertView.findViewById(R.id.arrow_expand);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
holder.tvQuestion.setText(mListQuestion.get(position));
holder.tvAns.setText(mListAnswer.get(position));
holder.ivArrow.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
if (flag == false)
{
Logger.d("arrow clicked when flag is false");
holder.tvAns.setVisibility(View.VISIBLE);
holder.ivArrow.setBackgroundResource(R.drawable.up_arrow);
flag = true;
}
else if (flag == true)
{
Logger.d("arrow clicked when flag is true");
holder.tvAns.setVisibility(View.GONE);
holder.ivArrow.setBackgroundResource(R.drawable.down_arrow);
flag = false;
}
notifyDataSetChanged();
}
});
return convertView;
}
static class ViewHolder {
TextView tvQuestion;
TextView tvAns;
Button ivArrow;
}
}
Can someone please tell what I am doing wrong here.
Thanks in Advance.
-Arindam.
public class ListAdapter extends BaseAdapter {
private Context context;
private List<String> mListQuestion = null;
private List<String> mListAnswer = null;
ViewHolder holder = null;
private List<Boolean> textViewVisibileState;
public ListAdapter(Context context, List<String> question, List<String> answer ) {
this.mListQuestion = question;
this.mListAnswer = answer;
this.context = context;
this.textViewVisibileState=new ArrayList<>(Arrays.asList(new Boolean[getCount()]));
Collections.fill(this.textViewVisibileState,false);
}
#Override
public Object getItem(int position)
{
return mListQuestion.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getCount() {
return mListQuestion.size();
}
#Override
#SuppressWarnings("deprecation")
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null)
{
LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.list_faq_item, null);
holder = new ViewHolder();
holder.tvQuestion = (TextView) convertView.findViewById(R.id.text);
holder.tvAns = (TextView) convertView.findViewById(R.id.anstext);
holder.ivArrow = (Button)convertView.findViewById(R.id.arrow_expand);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
holder.tvQuestion.setText(mListQuestion.get(position));
holder.tvAns.setText(mListAnswer.get(position));
if(textViewVisibileState.get(position))
{
holder.tvAns.setVisibility(View.GONE);
holder.ivArrow.setBackgroundResource(R.drawable.down_arrow);
}
else
{
Logger.d("arrow clicked when flag is false");
holder.tvAns.setVisibility(View.VISIBLE);
holder.ivArrow.setBackgroundResource(R.drawable.up_arrow);
}
holder.ivArrow.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
if (textViewVisibileState.get(position))
{
textViewVisibileState.set(position,false);
}
else
{
textViewVisibileState.set(position,true);
}
notifyDataSetChanged();
}
});
return convertView;
}
static class ViewHolder {
TextView tvQuestion;
TextView tvAns;
Button ivArrow;
}
}
This will work.
The variable flag is not context sensitive to object holder. So flag is always = false in your case. How about setVisibility(View.GONE) initially? And then setVisibility(View.VISIBLE) ONLY when ivArrow is clicked upon.
Calling notifyDataSetChanged() causes ListView to rebuild everything. It will remove its child views, call getView() for all the items that are visible, and thus you will rebind all the data for those items.
But your data hasn't actually changed. You haven't modified anything in the questions list, so binding the data again is meaningless. Instead you have tried to change something in your ViewHolder object, but there's no guarantee that the convertView you get after a notifyDataSetChanged() is for the same position as before, so it's possible that some other item has been affected (or perhaps none at all?).
Try removing the call to notifyDataSetChanged() from the OnClickListener. A visibility change should cause a re-layout of the view hierarchy, but as long as you haven't told ListView that the data has changed, it should keep all its current children.
Create an instance of the adapter, e.g Adapter myAdapter = new Adapter, set it to a listview or recyclerview e.g listview.setAdapter(mydapter) and everytime you add new data to it call adapter.notifyDataSetChanged()

Android - ListView with different heights in each row / getView()

I want to build a dynamic ListView (like a chat list with different layouts/bubbles).
My problem is, that each row has an individual height. My code below works,
but every time I scroll down or receive a new message,
the row with a different height gets heigher.
private class dialogAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public dialogAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
#Override
public boolean hasStableIds() {
return true;
}
public int getCount() {
return dialog.size();
}
public int getViewTypeCount() {
return 999999;
}
public Object getItem(int position) {
return dialog.get(position);
}
public int getItemViewType(int position) {
return position;
}
public String getType(int position) {
return dialogType.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
Log.w("DRAGII", "POS: "+position);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.bubble, null);
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.text);
holder.parser = new URLImageParser(holder.text);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if (position <= dialogCache.size())
dialogCache.add(position, Html.fromHtml((String)getItem(position),
holder.parser, null));
holder.text.setText(dialogCache.get(position));
holder.type = getType(position);
int bubble = R.drawable.bubble;
if (holder.type.equals("R")) bubble = R.drawable.bubble_right;
else if (holder.type.equals("L")) bubble = R.drawable.bubble_left;
holder.text.setBackgroundResource(bubble);
return convertView;
}
class ViewHolder {
TextView text;
String type = "B";
URLImageParser parser;
}
}
What should I do?
Solved this problem by using TableLayout instead of ListView.
if u are adding tableRow programmatically to tableLayout, you will have performance issues. Think it again and find a way by using listView

Listview items background

How to change the background image for list items, i am able to change only 1 item background at a time.
If there are 6 items on the list and if click on 3 items those 3 items background images should be changed, how it is possible
Below is my code
public class Places extends Activity {
private ListView listView;
private int selectedListItem = -1;
private Handler mHandler = new Handler();
private Vector<String> data;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.places_custom_list_view);
data = new Vector<String>();
// Add data as per your requirement
data.add("one");
data.add("two");
data.add("three");
data.add("four");
data.add("five");
listView = (ListView)findViewById(R.id.ListView01);
listView.setDivider(null);
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
selectedListItem = position;
((EfficientAdapter)listView.getAdapter()).notifyDataSetChanged();
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
// call any new activity here or do any thing you want here
}
}, 200L);
}
});
listView.setAdapter(new EfficientAdapter(getApplicationContext()));
}
private class EfficientAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public EfficientAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null || convertView.getTag() == null) {
convertView = mInflater.inflate(R.layout.places_custom_row_view, null);
holder = new ViewHolder();
holder.txtName = (TextView) convertView
.findViewById(R.id.name);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if(position == selectedListItem) {
holder.txtName.setBackgroundResource(R.drawable.cellbghover);
} else {
holder.txtName.setBackgroundResource(R.drawable.cellbgnew);
}
holder.txtName.setText(data.get(position));
return convertView;
}
}
static class ViewHolder {
TextView txtName;
}
Try this,it should work logically.(I didn't try it,btw! :P)
...
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
EfficientAdapter.saveState.put(position,"selected");
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
// call any new activity here or do any thing you want here
}
}, 200L);
}
});
...
private class EfficientAdapter extends BaseAdapter {
public static HashMap<Integer,String> saveState=new HashMap<Integer,String>();
private LayoutInflater mInflater;
public EfficientAdapter(Context context)
{
mInflater = LayoutInflater.from(context);
for(int i=0;i<5;i++)
{
saveState.put(i,"unselected");
}
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null || convertView.getTag() == null) {
convertView = mInflater.inflate(R.layout.places_custom_row_view, null);
holder = new ViewHolder();
holder.txtName = (TextView) convertView
.findViewById(R.id.name);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if(saveState.get(position).equals("selected"))
holder.txtName.setBackgroundResource(R.drawable.cellbghover);
else
holder.txtName.setBackgroundResource(R.drawable.cellbgnew);
holder.txtName.setText(data.get(position));
return convertView;
}
}
static class ViewHolder {
TextView txtName;
}
Every time you click on listview item whole listview is getting refreshed.
So if you want to show previously selected items also then need to keep record of all the item selected. and when listview refreshed you need to check that this positions are previously selected or not according to that set your color.
Hope this help you
try this
android:background="#drawable/img_list_background_repeater"
if(clickWord.size()!=0)
{
for(int i = 0;i<clickWord.size();i++){
if(clickWord.get(i).equalsIgnoreCase(adListText[position])&&clickIndex.get(i)==position){
wordChk.setBackgroundResource(R.drawable.star_1);
}
}
}
Here clickWord is an arraylist of items selected. so when items get selected it will be added in this arraylist and when arraylist is refreshed i check all this using this loop.

Categories

Resources