Android Recycler layouts not inflating properly why - android

I use an android recyclerview to inflate three layouts as shown in my code but the footer is not being inflated properly hence hides some data of the listview layout. Where is the problem with my code since I want the listview layout to be displayed as the last layout in the recyclerview adapter.
package com.news254.inception.newsapp;
import android.content.Intent;
import android.content.res.Configuration;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
public class Newspaper extends AppCompatActivity {
Toolbar mtoolbar;
String TITLES[] = {"Newspaper","Gossip","Entertainment","Sports","International","About","Exit"};
int ICONS[] = {R.drawable.newspaper,R.drawable.gossip,R.drawable.entertainment,R.drawable.sports,R.drawable.international,R.drawable.about,R.drawable.exit};
//Similarly we Create a String Resource for the name and email in the header
view
//And we also create a int resource for profile picture in the header view
Boolean isDrawerOpen =true;
private Toolbar toolbar; // Declaring the
Toolbar Object
RecyclerView mRecyclerView; // Declaring
RecyclerView
RecyclerView.Adapter mAdapter; // Declaring Adapter
For Recycler View
RecyclerView.LayoutManager mLayoutManager; // Declaring Layout
Manager as a linear layout manager
DrawerLayout Drawer; // Declaring
DrawerLayout
ActionBarDrawerToggle mDrawerToggle;
ImageView
Nation,Standard,Capital,Nairobian,BusinessDaily,EastAfrican,Star,Mwakilishi,Citizen;
String nation = "http://www.nation.co.ke";
String standard = "http://www.standardmedia.co.ke";
String star = "http://www.the-star.co.ke";
String nairobian = "http://www.sde.co.ke/m/thenairobian";
String eastafrican = "http://www.theeastafrican.co.ke";
String businessdaily = "http://www.businessdailyafrica.com";
String mwakilishi = "http://www.mwakilishi.com";
String capital = "http://www.capitalfm.co.ke";
String citizen = "http://www.theweeklycitizen.co.ke";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_news);
mtoolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mtoolbar);
mRecyclerView = (RecyclerView) findViewById(R.id.RecyclerView); // Assigning the RecyclerView Object to the xml View
mRecyclerView.setHasFixedSize(true); // Letting the system know that the list objects are of fixed size
mAdapter = new MyAdapter(TITLES,ICONS); // Creating the Adapter of MyAdapter class(which we are going to see in a bit)
// And passing the titles,icons,header view name, header view email,
// and header view profile picture
mRecyclerView.setAdapter(mAdapter); // Setting the adapter to RecyclerView
mLayoutManager = new LinearLayoutManager(this); // Creating a layout Manager
mRecyclerView.setLayoutManager(mLayoutManager); // Setting the layout Manager
Nation = (ImageView) findViewById(R.id.nation);
Nation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent p = new Intent(Newspaper.this,Browser.class);
p.putExtra("site",nation);
startActivity(p);
}
});
Standard = (ImageView) findViewById(R.id.standard);
Standard.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent p = new Intent(Newspaper.this,Browser.class);
p.putExtra("site",standard);
startActivity(p);
}
});
Star = (ImageView) findViewById(R.id.star);
Star.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent p = new Intent(Newspaper.this,Entertainment.class);
p.putExtra("site",star);
startActivity(p);
}
});
Capital = (ImageView) findViewById(R.id.capital);
Capital.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent p = new Intent(Newspaper.this,Browser.class);
p.putExtra("site",capital);
startActivity(p);
}
});
Nairobian = (ImageView) findViewById(R.id.nairobian);
Nairobian.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent p = new Intent(Newspaper.this,Browser.class);
p.putExtra("site",nairobian);
startActivity(p);
}
});
Citizen = (ImageView) findViewById(R.id.citizen);
Citizen.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent p = new Intent(Newspaper.this,Browser.class);
p.putExtra("site",citizen);
startActivity(p);
}
});
EastAfrican = (ImageView) findViewById(R.id.eastafrican);
EastAfrican.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent p = new Intent(Newspaper.this,Browser.class);
p.putExtra("site",eastafrican);
startActivity(p);
}
});
BusinessDaily = (ImageView) findViewById(R.id.businessdaily);
BusinessDaily.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent p = new Intent(Newspaper.this,Browser.class);
p.putExtra("site",businessdaily);
startActivity(p);
}
});
Mwakilishi = (ImageView) findViewById(R.id.mwakilishi);
Mwakilishi.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent p = new Intent(Newspaper.this,Browser.class);
p.putExtra("site",mwakilishi);
startActivity(p);
}
});
Drawer = (DrawerLayout) findViewById(R.id.DrawerLayout); // Drawer object Assigned to the view
mDrawerToggle = new ActionBarDrawerToggle(this,Drawer,toolbar,R.string.drawer_open,R.string.drawer_close){
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
// code here will execute once the drawer is opened( As I dont want anything happened whe drawer is
// open I am not going to put anything here)
}
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
// Code here will execute once drawer is closed
}
/* #Override
public void onDrawerSlide(View drawerView, float slideOffset) {
if(slideOffset >.55 && !isDrawerOpen)
{
onDrawerOpened(drawerView);
isDrawerOpen=true;
}
else if (slideOffset <.45 && isDrawerOpen)
{
onDrawerClosed(drawerView);
isDrawerOpen = false;
}
// super.onDrawerSlide(drawerView, slideOffset);
}*/
}; // Drawer Toggle Object Made
Drawer.setDrawerListener(mDrawerToggle);
// / Drawer Listener set to the Drawer toggle
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mDrawerToggle.setDrawerIndicatorEnabled(true);
}
#Override
public void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_news, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if(mDrawerToggle.onOptionsItemSelected(item))
{
return true;
}
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
} }
package com.news254.inception.newsapp;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
/**
* Created by hp1 on 28-12-2014.
*/
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private static final int TYPE_FOOTER = 2; // Declaring Variable to
Understand which View is being worked on
// IF the view under inflation and population is header or Item
private static final int TYPE_ITEM = 1;
private static final int TYPE_HEADER= 0;
private String mNavTitles[]; // String Array to store the passed titles
Value from MainActivity.java
private int mIcons[]; // Int Array to store the passed icons
resource value from MainActivity.java
private int mfooter[];
private String mtitleFoot[];
int Holderid;
// Creating a ViewHolder which extends the RecyclerView View Holder
// ViewHolder are used to to store the inflated views in order to
recycle them
public static class ViewHolder extends RecyclerView.ViewHolder {
int Holderid;
TextView textView;
ImageView imageView;
ImageView about;
TextView name;
public ViewHolder(View itemView,int ViewType) { // Creating ViewHolder Constructor with View and viewType As a parameter
super(itemView);
// Here we set the appropriate view in accordance with the the view type as passed when the holder object is created
if(ViewType == TYPE_ITEM) {
textView = (TextView) itemView.findViewById(R.id.rowText); // Creating TextView object with the id of textView from item_row.xml
imageView = (ImageView) itemView.findViewById(R.id.rowIcon);// Creating ImageView object with the id of ImageView from item_row.xml
Holderid = 1; // setting holder id as 1 as the object being populated are of type item row
}
else if(ViewType == TYPE_FOOTER){
about = (ImageView) itemView.findViewById(R.id.image); // Creating Text View object from header.xml for name
name = (TextView) itemView.findViewById(R.id.text); // Creating Text View object from header.xml for email
// Creating Image view object from header.xml for profile pic
Holderid =2; // Setting holder id = 0 as the object being populated are of type header view
}
else if(ViewType == TYPE_HEADER)
{
Holderid =0;
}
}
}
MyAdapter(String Titles[],int Icons[]){ // MyAdapter Constructor
with titles and icons parameter
// titles, icons, name, email, profile pic are passed from the
main activity as we
mNavTitles = Titles; //have seen earlier
mIcons = Icons;
//here we assign those passed values to the values
we declared here
//in adapter
}
//Below first we ovverride the method onCreateViewHolder which is called when
the ViewHolder is
//Created, In this method we inflate the item_row.xml layout if the
viewType is Type_ITEM or else we inflate header.xml
// if the viewType is TYPE_HEADER
// and pass it to the view holder
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int
viewType) {
if (viewType == TYPE_ITEM) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.listview,parent,false); //Inflating the layout
ViewHolder vhItem = new ViewHolder(v,viewType); //Creating ViewHolder and passing the object of type view
return vhItem; // Returning the created object
//inflate your layout and pass it to view holder
}
else if (viewType == TYPE_HEADER) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.header, parent, false); //Inflating the layout
ViewHolder vhHeader = new ViewHolder(v, viewType); //Creating ViewHolder and passing the object of type view
return vhHeader; //returning the object created
}
else if (viewType == TYPE_FOOTER) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.footer, parent, false); //Inflating the layout
ViewHolder vhHeader = new ViewHolder(v, viewType); //Creating ViewHolder and passing the object of type view
return vhHeader; //returning the object created
}
return null;
}
//Next we override a method which is called when the item in a row is
needed to be displayed, here the int position
// Tells us item at which position is being constructed to be displayed
and the holder id of the holder object tell us
// which view type is being created 1 for item row
#Override
public void onBindViewHolder(MyAdapter.ViewHolder holder, int
position) {
if(holder.Holderid ==1) { // as the list view is going to be called after the header view so we decrement the
// position by 1 and pass it to the holder while setting the text and image
holder.textView.setText(mNavTitles[position-2]); // Setting the Text with the array of our Titles
holder.imageView.setImageResource(mIcons[position-2]);// Settimg the image with array of our icons
}
else if (holder.Holderid ==2){
holder.about.setImageResource(mIcons[position]); // Similarly we set the resources for header view
holder.name.setText(mNavTitles[position]);
}
else if (holder.Holderid ==0){
}
}
// This method returns the number of items present in the list
#Override
public int getItemCount() {
return mNavTitles.length+2;
// the number of items in the list will be +1 the titles including the header view.
}
// Witht the following method we check what type of view is being passed
#Override
public int getItemViewType(int position) {
if (position == 0) {
return TYPE_HEADER;
}
else if (position ==2) {
return TYPE_FOOTER ;
}
else {
return TYPE_ITEM;
}
}
private boolean isPositionHeader(int position) {
return position == 0;
}
}

Change this
#Override
public int getItemViewType(int position) {
if (position == 0) {
return TYPE_HEADER;
}
else if (position ==2) {
return TYPE_FOOTER ;
}
else {
return TYPE_ITEM;
}
}
To
#Override
public int getItemViewType(int position) {
if(position==0){
return TYPE_HEADER;
}
else if((mNavTitles.length+ 1) == position){
return TYPE_FOOTER;
}else{
return TYPE_ITEM;
}
}

Related

Get selected item position of RecyclerView

I am trying to get position of the clicked item in RecyclerView. In adapter class, I am trying to create intent and send clicked item's contents. Also I created popup menu for two option. It is in adapter class too. onBindViewHolder position is works for puting contents in the rows of RecyclerView. However I couldn't reach that position from outside of method.
This is adapter class.
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> implements PopupMenu.OnMenuItemClickListener {
public ArrayList<MovieModel.Results> resultList;
public Context context;
public RecyclerViewAdapter(ArrayList<MovieModel.Results> list, Context context) {
this.resultList = list;
this.context = context;
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView posterImage;
ImageView addIcon;
TextView movieName;
TextView date;
TextView overview;
public ViewHolder(#NonNull View itemView) {
super(itemView);
posterImage = itemView.findViewById(R.id.movie_poster);
addIcon = itemView.findViewById(R.id.addImage);
movieName = itemView.findViewById(R.id.movieNameText);
date = itemView.findViewById(R.id.dateText);
overview = itemView.findViewById(R.id.overviewText);
}
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.movie_list_2, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
if (position < getItemCount()) {
String title = resultList.get(position).getTitle();
String date = resultList.get(position).getRelease_date();
String overview = resultList.get(position).getOverview();
String posterPath = resultList.get(position).getPoster_path();
holder.movieName.setText(title);
holder.date.setText(date);
holder.overview.setText(overview);
if (posterPath == null) {
holder.posterImage.setImageDrawable(context.getDrawable(R.drawable.no_poster));
} else {
Glide.with(context).load(FeedActivity.BASE_PHOTO_URL + posterPath).into(holder.posterImage);
}
int finalPosition = position;
holder.addIcon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Toast.makeText(context, "You clicked : " + finalPosition, Toast.LENGTH_SHORT).show();
showPopup(v);
}
});
}
position++;
}
private void showPopup(View v) {
PopupMenu popup = new PopupMenu(context,v);
popup.setOnMenuItemClickListener(this);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.menu, popup.getMenu());
popup.show();
}
#Override
public boolean onMenuItemClick(MenuItem item) {
// Here I need to position of clicked item in Recyclerview, and I will get title, date etc.
int pos;
if(item.getItemId() == R.id.menuAdd){
// Find here to get position of clicked movie.
String title = resultList.get(pos).getTitle();
String date = resultList.get(pos).getRelease_date();
String overview = resultList.get(pos).getOverview();
String posterpath = resultList.get(pos).getPoster_path();
Intent intent1 = new Intent(context,ListActivity.class);
intent1.putExtra("title",title);
intent1.putExtra("date",date);
intent1.putExtra("overview",overview);
intent1.putExtra("posterpath",posterpath);
context.startActivity(intent1);
return true;
}
else if(item.getItemId() == R.id.menuShowDetails){
int movieId = resultList.get(pos).getMovieId();
Intent intent1 = new Intent(context, MovieDetails.class);
intent1.putExtra("movie_id",movieId);
context.startActivity(intent1);
return true;
}
return false;
}
#Override
public int getItemCount() {
return resultList.size();
}
}
You can use the ViewHolder's getAdapterPosition() to retrieve the item's position within an interface method. Then store the clicked position in a member variable.
Additionally, there shouldn't be a need to call position++ from within your onBindViewHolder.
// Create a member variable to store the clicked position
public int clickedPos = -1;
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
// ...
holder.addIcon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// When you're inside the click listener interface,
// you can access the position using the ViewHolder.
// We'll store the position in the member variable in this case.
clickedPos = holder.getAdapterPosition();
}
});
// Remove the 'position++' call as the position should already be handled without explicitly updating it.
}
#Override
public boolean onMenuItemClick(MenuItem item) {
// You can use clickedPos here to perform whatever tasks you need.
// ...
}

How to get gridview multiple positions and store into array variable

Now I am displaying images in grid-view, it working fine. In that grid-view i am going to select few images, i want store selected multiple images position in array variable (example: if i select position 1, 4 ,10. i want that particular position id and i want to store it array like 1,4,10,15,). I will put my activity and adapter code below. Thank you in advance.
Activity
public class EM_event_total_userSeats extends AppCompatActivity implements RestCallback,AdapterView.OnItemClickListener {
String user_id,first_name,last_name,name,emailid,contact_no,gender1,date_of_birth,country_id,postal_code,rolename,profession_response,Street_Address,City,photo;
GridView GridUserSeats;
;
TextView textView1,textView2,Tvposition;
ImageView Ivseats;
public static EM_event_total_userseatsAdapter adapter;
ArrayList<EM_event_total_UserSeatsModel> EMeventuserseatslist;
View savedView;
View previous = null;
String event_id = "EVEPRI62";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.em_event_total_user_seats);
initviews();
callSeatsApi();
GridUserSeats.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
String a = String.valueOf(position);
Toast.makeText(EM_event_total_userSeats.this, a + "#Selected", Toast.LENGTH_SHORT).show();
v.setBackgroundColor(Color.GREEN);
adapter.notifyDataSetChanged();
}
});
}
private void initviews() {
GridUserSeats=(GridView)findViewById(R.id.GridUserSeats);
GridUserSeats.setOnItemClickListener(this);
textView1=(TextView) findViewById(R.id.textView1);
// textView2=(TextView) findViewById(R.id.textView2);
Intent intent = getIntent();
first_name = intent.getStringExtra("first_name");
last_name = intent.getStringExtra("last_name");
}
private void callSeatsApi() {
HashMap<String, String> map = new HashMap<String, String>();
map.put("events", event_id);
RestService.getInstance(EM_event_total_userSeats.this).getUserSeats(map, new MyCallback<ArrayList<EM_event_total_UserSeatsModel>>(EM_event_total_userSeats.this,
EM_event_total_userSeats.this, true, "Finding seats....", GlobalVariables.SERVICE_MODE.EM_SEATS));
}
#Override
public void onFailure(Call call, Throwable t, GlobalVariables.SERVICE_MODE mode) {
}
#Override
public void onSuccess(Response response, GlobalVariables.SERVICE_MODE mode)
{
switch (mode)
{
case EM_SEATS:
EMeventuserseatslist = (ArrayList<EM_event_total_UserSeatsModel>)response.body();
adapter = new EM_event_total_userseatsAdapter(EMeventuserseatslist, getApplicationContext());
GridUserSeats.setAdapter(adapter);
break;
}
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
}
Adapter
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
import java.util.List;
import cfirst.live.com.R;
import cfirst.live.com.model.BasketModel;
import cfirst.live.com.model.EM_event_total_UserSeatsModel;
public class EM_event_total_userseatsAdapter extends ArrayAdapter<EM_event_total_UserSeatsModel> implements View.OnClickListener {
ArrayList<EM_event_total_UserSeatsModel> dataSet;
public ArrayList<EM_event_total_UserSeatsModel> EMeventuserseatslist = new ArrayList<EM_event_total_UserSeatsModel>();
Context mContext;
ViewHolder holder;
String user_seats;
private int[] tagCollection;
private String[] mobileValues;
private String[] mobileValuesD;
private static class ViewHolder {
TextView TvEmUserSeats;
ImageView IvUsreSeats,available,selctedimag;
}
private String[] strings;
List<Integer> selectedPositions = new ArrayList<>();
public EM_event_total_userseatsAdapter(ArrayList<EM_event_total_UserSeatsModel> data, Context context) {
super(context, R.layout.list_em_get_seats, data);
this.dataSet = data;
this.mContext=context;
}
public int getTagFromPosition(int position) {
return tagCollection[position];
}
#Override
public void onClick(View v) {
int position=(Integer) v.getTag();
Object object= getItem(tagCollection[position]);
EM_event_total_UserSeatsModel dataModel=(EM_event_total_UserSeatsModel) object;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
EM_event_total_UserSeatsModel dataModel = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
ViewHolder viewHolder; // view lookup cache stored in tag
final View result;
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.list_em_get_seats, parent, false);
viewHolder.TvEmUserSeats = (TextView) convertView.findViewById(R.id.TvEmUserSeats);
viewHolder.IvUsreSeats = (ImageView) convertView.findViewById(R.id.IvUsreSeats);
result=convertView;
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
result=convertView;
}
String blue_available = "seat3.png";
String red_booked = "seat1.png";
String get_seat = dataModel.getBookedStatus();
viewHolder.TvEmUserSeats.setText(dataModel.getSeatName());
if(Integer.parseInt(get_seat) == 1){
Picasso.with(mContext).load("imageurl + red_booked).into(viewHolder.IvUsreSeats);
}else
{
Picasso.with(mContext).load("imageurl + blue_available).into(viewHolder.IvUsreSeats);
}
return convertView;
}
}
It's simple. You can use SparseBooleanArray for this purpose. Just add the following methods as is in your adapter:
public void toggleSelection(int item) {
if (selectedItems.get(item, false)) {
selectedItems.delete(item);
} else {
selectedItems.put(item, true);
}
notifyDataSetChanged();
}
public void setSelectedItems(List<Object> objects) {
if (objects != null) {
for (Object object : objects) {
toggleSelection(object.getId());
}
notifyDataSetChanged();
}
}
public void clearSelections() {
selectedItems.clear();
notifyDataSetChanged();
}
public int getSelectedItemCount() {
return selectedItems.size();
}
public List<Integer> getSelectedItems() {
List<Integer> items =
new ArrayList<Integer>(selectedItems.size());
for (int i = 0; i < selectedItems.size(); i++) {
items.add(selectedItems.keyAt(i));
}
return items;
}
Use the set selection method to store the selected status of your item.
Don't forget to initialize SparseBooleanArray in your constructor.
SparseBooleanArray SparseBooleanArray = new SparseBooleanArray();
After that, use toggleSelection(position); to change the selected status of an item, then after performing selections, call getSelectedItem() to get the selected items in an array.
// create an Arraylist and add the selected position in a list
List <int> selectedArray = new ArrayList<>();
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
int click = (int) parent.getItemAtPosition(position);
selectedArray.add(click);
}

Dynamic ListView issue on Android

Currently I am working on an Android app and use parse as backend where I have created a ListView of nearby places dynamically. But I face the following design issue: When the user clicks on a place, a view must appear under the clicked item.
And I have faced a problem with grouping the place, as you can see in figure 1, there are many branches for HSBC bank. In which case they are under HSBC.
I have tried expandable ListView before, but it does not give much customization for child view , just simple one.
my BaseAdapter:
import java.util.ArrayList;
import java.util.List;
import com.parse.ParseGeoPoint;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewManager;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class ListViewAdapter extends BaseAdapter {
// Declare Variables
Context context;
LayoutInflater inflater;
//ImageLoader imageLoader;
private List<AnywallPost> AnywallPostlist = null;
private ArrayList<AnywallPost> arraylist;
public ListViewAdapter(Context context,
List<AnywallPost> AnywallPostlist) {
this.context = context;
this.AnywallPostlist = AnywallPostlist;
inflater = LayoutInflater.from(context);
this.arraylist = new ArrayList<AnywallPost>();
this.arraylist.addAll(AnywallPostlist);
}
public class ViewHolder {
TextView distance;
TextView name;
}
#Override
public int getCount() {
return AnywallPostlist.size();
}
#Override
public Object getItem(int position) {
return AnywallPostlist.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(final int position, View view, ViewGroup parent) {
final ViewHolder holder;
final View row=view;
if (view == null) {
holder = new ViewHolder();
view = inflater.inflate(R.layout.user_custom, null);
// Locate the TextViews in listview_item.xml
holder.distance = (TextView) view.findViewById(R.id.disView);
holder.name = (TextView) view.findViewById(R.id.nameView);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
// Set the results into TextViews
holder.name.setText(AnywallPostlist.get(position).getText());
holder.distance.setText(AnywallPostlist.get(position).getDis());
//Listen for ListView Item Click
view.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Toast.makeText(context,AnywallPostlist.get(position).getText(), Toast.LENGTH_LONG).show();
}
});
return view;
}
}
.
import com.parse.ParseClassName;
import com.parse.ParseGeoPoint;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import com.parse.ParseUser;
/**
* Data model for a post.
*/
#ParseClassName("places")
public class AnywallPost extends ParseObject {
public String getText() {
return getString("text");
}
public void setText(String value) {
put("text", value);
}
public String getBank() {
return getString("bank");
}
public void setBank(String value) {
put("bank", value);
}
public ParseUser getUser() {
return getParseUser("user");
}
public void setUser(ParseUser value) {
put("user", value);
}
public String getType()
{
return getString("type");
}
public void setType(String value)
{
put("type",value);
}
public ParseGeoPoint getLocation() {
return getParseGeoPoint("location");
}
public void setLocation(ParseGeoPoint value) {
put("location", value);
}
public String getDis()
{
return getString("dis");
}
public void setdis(String value)
{
put("dis",value);
}
public static ParseQuery<AnywallPost> getQuery() {
return ParseQuery.getQuery(AnywallPost.class);
}
}
.
switch (getItemViewType(position)) {
case 0:
Bank bank = (Bank) getItem(position);
holder.name.setText(bank.name);
String str = String.valueOf(bank.numBranches);
holder.cn.setText(str);
imageLoader.DisplayImage(bank.image,
holder.logo);
Toast.makeText(getActivity(), "img"+bank.image,Toast.LENGTH_LONG).show();
// ... set the image here
// ... set the number of branches here
break;
case 1:
branch = (AnywallPost) getItem(position);
holder.name.setText(branch.getText());
holder.distance.setText(branch.getDis());
holder.b.setText(branch.getbranch());
imageLoader.DisplayImage(branch.getimg(),
holder.logo);
break;
case 2:
branch = (AnywallPost) getItem(position);
holder.name.setText(branch.getText());
holder.distance.setText(branch.getDis());
holder.b.setText(branch.getbranch());
imageLoader.DisplayImage(branch.getimg(),
holder.logo);
// ... set values for all the expanded view widgets too
break;
}
I have used this code to get image from parse and I add it to AnywallPost
ParseFile image = (ParseFile) country.get("image");
AnywallPost map = new AnywallPost();
map.setimg(image.getUrl());
then, I used this code to load the image and it worked fine
imageLoader.DisplayImage(AnywallPostlist.get(position).getimg(),
holder.logo);
Here is my idea:
You will have two layouts, a brief one with the name & distance, and an expanded one with the name & distance plus all the details.
The brief layout will have a view type of 0, and the expanded layout will have a view type of 1.
When you click on the item, you set a flag in the list model to indicate that the view has switched from brief view to long view. So you should see the view switch. If you click on an expanded view, it will revert to brief view.
I don't have a way to test this, but here is how I think the code will look:
public class ListViewAdapter extends BaseAdapter {
// Declare Variables
Context context;
LayoutInflater inflater;
//ImageLoader imageLoader;
private List<AnywallPost> AnywallPostlist = null;
private ArrayList<AnywallPost> arraylist;
/** this array holds a flag for each item to show if it is in brief view more or expanded view mode*/
private boolean[] expandedView;
public ListViewAdapter(Context context,
List<AnywallPost> AnywallPostlist) {
this.context = context;
this.AnywallPostlist = AnywallPostlist;
inflater = LayoutInflater.from(context);
this.arraylist = new ArrayList<AnywallPost>();
this.arraylist.addAll(AnywallPostlist);
this.expandedView = new boolean[AnywallPostlist.size()];
}
public class ViewHolder {
TextView distance;
TextView name;
// ... add all your expanded view fields here too
}
#Override
public int getCount() {
return AnywallPostlist.size();
}
#Override
public int getViewTypeCount() {
return 2; // brief & expanded
}
#Override
public int getItemViewType(int position) {
return expandedView[position] ? 1 : 0;
}
#Override
public Object getItem(int position) {
return AnywallPostlist.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(final int position, View view, ViewGroup parent) {
final ViewHolder holder;
final View row=view;
if (view == null) {
holder = new ViewHolder();
int layout = expandedView[position] ? R.layout.user_custom_expanded : R.layout.user_custom;
view = inflater.inflate(layout, parent, false);
// Locate the TextViews in listview_item.xml
holder.distance = (TextView) view.findViewById(R.id.disView);
holder.name = (TextView) view.findViewById(R.id.nameView);
if (expandedView[position]) {
// ... locate all the expanded view widgets too
}
view.setTag(holder);
} else {
// because the view type is determined by expandedView[position], the correct layout will be recycled here
holder = (ViewHolder) view.getTag();
}
// Set the results into TextViews
holder.name.setText(AnywallPostlist.get(position).getText());
holder.distance.setText(AnywallPostlist.get(position).getDis());
if (expandedView[position]) {
// ... set all the values for your expanded view too
}
//Listen for ListView Item Click
view.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
if (expandedView[position]) {
// this is expanded view so toggle it back to brief view
expandedView[position] = false;
} else {
// clear any expanded views elsewhere
expandedView = new boolean[AnywallPostlist.size()];
// toggle brief view to expanded
expandedView[position] = true;
}
// forces the ListView to refresh and convert the brief view into an expanded view and vice versa.
ListViewAdapter.this.notifyDataSetChanged();
// Toast.makeText(context,AnywallPostlist.get(position).getText(), Toast.LENGTH_LONG).show();
}
});
if (expandedView[position]) {
// ... add all your event listeners for the expanded view widgets
}
return view;
}
}
You can also add a toggle button with expand/collapse indicator to the view to control the expand/collapse so you don't click anywhere on the view to change it.
You can do this with an ExpandableListView if you want, you just need to change to an ExpandableListAdapter and do your layouts a little differently.
Here is some code to make a heterogeneous list:
Take a really good look at the constructor to see how I divided up the branches by bank them strung them all together into one big list.
The list is just an Object array, so you figure out what the item is like this:
If it's a Bank, then well, it's a bank.
If it's an AnywallPost and expandedView[position] == false then it's a branch, brief view
If it's an AnywallPost and expandedView[position] == true then it's a branch, expanded view
public class Bank {
private String name;
private String image; // maybe this needs to be URL?
private int numBranches;
}
public class ListViewAdapter extends BaseAdapter {
// Declare Variables
Context context;
LayoutInflater inflater;
ImageLoader imageLoader;
private Object[] masterList;
/** this array holds a flag for each item to show if it is in brief view more or expanded view mode*/
private boolean[] expandedView;
public ListViewAdapter(Context context,
List<AnywallPost> AnywallPostlist) {
this.context = context;
inflater = LayoutInflater.from(context);
/*
* Phase I -- get list of banks and organize the branches by bank
*/
int count = 0;
List<String bankNames = new ArrayList<String>();
List<Bank> banks = new ArrayList<Bank>();
Map<String, Bank> bankMap = new HashMap<String, Bank>();
Map<String, List<AnywallPost>> mappedBranches = new HashMap<String, List<AnywallPost>>();
Bank bank = null;
List<AnywallPost> branches = null;
for (AnywallPost branch : AnywallPostlist) {
// have we started a branch list for this bank?
if (! bankNames.contains(branch.getBank())) { // no we haven't
// remember the bank name
bankNames.add(branch.getBank());
// init a new Bank
bank = new Bank();
bank.name = branch.getBank();
bank.image = branch.getImg(); // if this is URL make image in Bank a URL
banks.add(bank);
bankMap.put(bank.name, bank);
count++;
// create a list for this bank's branches and index it by bank
branches = new ArrayList<AnywallPost>();
mappedBranches.put(branch.getBank(), branches);
} else { // yes we have
// get the bank for this name
// this fixes the problem with the branch counts
bank = bankMap.get(branch.getBank());
// get the branch list we already created for this bank
branches = mappedBranches.get(branch.getBank());
}
// remember the branch for this bank
branches.add(branch);
count++;
// increment the number of branches for this bank
bank.numBranches++;
}
/*
* Phase II -- sort the banks and branches
*/
// ... here you can order the banks by name, branches by distance, etc.
/*
* Phase III -- create the mixed list
*/
int index = 0;
masterList = new Object[count];
for (Bank bank : banks) {
// append a bank to the list
masterList[index] = bank;
index++;
for (AnywallPost branch : mappedBranches.get(bank.name)) {
// append a branch to the list
masterList[index] = branch;
index++;
}
}
this.expandedView = new boolean[count];
}
public class ViewHolder {
TextView distance;
TextView name;
ImageView logo;
// ... add all your expanded view fields here too
}
#Override
public int getCount() {
return masterList.length;
}
#Override
public int getViewTypeCount() {
return 4; // bank brief, bank expanded, branch brief & branch expanded
}
#Override
public Object getItem(int position) {
return masterList[position];
}
#Override
public int getItemViewType(int position) {
if (getItem(position) instanceof Bank) {
return expandedView[position] ? 1 : 0;
}
return expandedView[position] ? 3 : 2;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View view, ViewGroup parent) {
final ViewHolder holder;
final View row=view;
if (view == null) {
holder = new ViewHolder();
int layout = 0;
switch (getItemViewType(position)) {
case 0:
layout = R.layout.bank_brief;
break;
case 1:
layout = R.layout.bank_expanded;
break;
case 2:
layout = R.layout.branch_brief;
break;
case 3:
layout = R.layout.branch_expanded;
break;
}
view = inflater.inflate(layout, parent, false);
switch (getItemViewType(position)) {
case 0:
holder.name = (TextView) view.findViewById(R.id.nameView);
break;
case 1:
holder.name = (TextView) view.findViewById(R.id.nameView);
// ... locate all the bank expanded view widgets too
break;
case 2:
holder.name = (TextView) view.findViewById(R.id.nameView);
holder.distance = (TextView) view.findViewById(R.id.disView);
break;
case 3:
holder.name = (TextView) view.findViewById(R.id.nameView);
holder.distance = (TextView) view.findViewById(R.id.disView);
// ... locate all the expanded view widgets too
break;
}
view.setTag(holder);
} else {
// because the view type is determined by expandedView[position], the correct layout will be recycled here
holder = (ViewHolder) view.getTag();
}
AnywallPost branch = null;
switch (getItemViewType(position)) {
case 0:
Bank bank = (Bank) getItem(position);
holder.name.setText(bank.name);
imageLoader.DisplayImage(bank.image, holder.logo);
// ... set the number of branches here
break;
case 1:
holder.name.setText(bank.name);
imageLoader.DisplayImage(bank.image, holder.logo);
// ... set the number of branches here
break;
case 1:
branch = (AnywallPost) getItem(position);
holder.name.setText(branch.getText());
holder.distance.setText(branch.getDis());
break;
case 2:
branch = (AnywallPost) getItem(position);
holder.name.setText(branch.getText());
holder.distance.setText(branch.getDis());
// ... set values for all the expanded view widgets too
break;
}
//Listen for ListView Item Click
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
if (expandedView[position]) {
// this is expanded view so toggle it back to brief view
expandedView[position] = false;
} else {
// clear any expanded views elsewhere
expandedView = new boolean[expandedView.length];
// toggle brief view to expanded
expandedView[position] = true;
}
if (getItem(position) instanceof AnywallPost) { // only for branches
// AnywallPost branch = (AnywallPost) getItem(position);
// Toast.makeText(context, branch.getText(), Toast.LENGTH_LONG).show();
}
// forces the ListView to refresh and convert the brief view into an expanded view and vice versa.
notifyDataSetChanged();
}
});
if (expandedView[position]) {
// ... add all your event listeners for the expanded view widgets
}
return view;
}
}

How to add a new set of items in a sliding menu?

I want to add another block, or set, or whatever it is called, of items in my sliding menu but I can't figure out what to change to the code of the first... In my sliding menu I have 6 items, but I to have 4 items to the first title, and then, another title, and another 2 items.. but i can't figure out what do I have to change to my first block code.. Thanks a lot !!!!
Here is my MainActivity.java:
package com.orar.cngcnasaud;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
public class MainActivity extends Activity implements OnClickListener {
private ListView mDrawerList;
private DrawerLayout mDrawer;
private CustomActionBarDrawerToggle mDrawerToggle;
private String[] menuItems;
private static final String TAG = "AudioDemo";
private static final String isPlaying = "Media is Playing";
private static final String notPlaying = "Media has stopped Playing";
MediaPlayer player;
Button playerButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_drawer);
player = MediaPlayer.create(this, R.raw.gc);
player.setLooping(false); // Set looping
// Get the button from the view
playerButton = (Button) this.findViewById(R.id.buttonmp);
playerButton.setText(R.string.play_label);
playerButton.setTextColor(Color.WHITE);
playerButton.setOnClickListener((OnClickListener) this);
// enable ActionBar app icon to behave as action to toggle nav drawer
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
// set a custom shadow that overlays the main content when the drawer
// opens
mDrawer.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
_initMenu();
mDrawerToggle = new CustomActionBarDrawerToggle(this, mDrawer);
mDrawer.setDrawerListener(mDrawerToggle);
}
public void onClick(View v) {
Log.d(TAG, "onClick: " + v);
if (v.getId() == R.id.buttonmp) {
playPause();
}
}
private void demoPause() {
// TODO Auto-generated method stub
player.pause();
playerButton.setText(R.string.play_label);
Log.d(TAG, notPlaying);
}
private void playPause() {
// TODO Auto-generated method stub
if(player.isPlaying()) {
demoPause();
} else {
demoPlay();
}
}
private void demoPlay() {
// TODO Auto-generated method stub
player.start();
playerButton.setText(R.string.stop_label);
Log.d(TAG, isPlaying);
}
private void _initMenu() {
NsMenuAdapter mAdapter = new NsMenuAdapter(this);
// Add Header
mAdapter.addHeader(R.string.ns_menu_main_header);
// Add first block
menuItems = getResources().getStringArray(
R.array.ns_menu_items);
String[] menuItemsIcon = getResources().getStringArray(
R.array.ns_menu_items_icon);
int res = 0;
for (String item : menuItems) {
int id_title = getResources().getIdentifier(item, "string",
this.getPackageName());
int id_icon = getResources().getIdentifier(menuItemsIcon[res],
"drawable", this.getPackageName());
NsMenuItemModel mItem = new NsMenuItemModel(id_title, id_icon);
if (res==1) mItem.counter=0; //it is just an example...
if (res==3) mItem.counter=0; //it is just an example...
mAdapter.addItem(mItem);
res++;
}
mDrawerList = (ListView) findViewById(R.id.drawer);
if (mDrawerList != null)
mDrawerList.setAdapter(mAdapter);
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
/*
* The action bar home/up should open or close the drawer.
* ActionBarDrawerToggle will take care of this.
*/
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle your other action bar items...
return super.onOptionsItemSelected(item);
}
private class CustomActionBarDrawerToggle extends ActionBarDrawerToggle {
public CustomActionBarDrawerToggle(Activity mActivity,DrawerLayout mDrawerLayout){
super(
mActivity,
mDrawerLayout,
R.drawable.ic_drawer,
R.string.ns_menu_open,
R.string.ns_menu_close);
}
#Override
public void onDrawerClosed(View view) {
getActionBar().setTitle(getString(R.string.ns_menu_close));
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
#Override
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(getString(R.string.ns_menu_open));
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
}
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mDrawerList.setItemChecked(position, true);
mDrawer.closeDrawer(mDrawerList);
if (position == 1) {
Intent intent = new Intent(MainActivity.this, Istoric.class);
startActivity(intent);
mDrawer.closeDrawers();
}
else if (position == 2) {
Intent intent2 = new Intent(MainActivity.this, Profesori.class);
startActivity(intent2);
mDrawer.closeDrawers();
}
if (position == 3) {
Intent intent3 = new Intent(MainActivity.this, Elevi.class);
startActivity(intent3);
mDrawer.closeDrawers();
}
if (position == 4) {
Intent intent4 = new Intent(MainActivity.this, ShowImageActivity.class);
startActivity(intent4);
mDrawer.closeDrawers();
}
if (position == 5) {
Intent intent5 = new Intent(MainActivity.this, Despre.class);
startActivity(intent5);
mDrawer.closeDrawers();
}
if (position == 6) {
Intent intent6 = new Intent(MainActivity.this, Feedback.class);
startActivity(intent6);
mDrawer.closeDrawers();
}
}
}
}
Thanks again !
I assume you want to achieve something similar to what is in the following picture:
You will have to modify your list adapter(NsMenuAdapter) to support two types of view - item and title where item is clickable and title is just kind of group header. Adapter should takes array/list of objects and every object should have type attribute. This will probably complicate a little OnItemClickListener.
I'm posting my example of that kind list adapter. In my case I created NavigationDrawerItem model to hold information about item type, item 'clickability' and what action should be triggered after item get clicked.
public class NavigationDrawerAdapter extends ArrayAdapter<NavigationDrawerItem> {
private static final String TAG = "NavigationDrawerAdapter";
public NavigationDrawerAdapter(Context context, int resource, NavigationDrawerItem[] objects) {
super(context, resource, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (null == convertView) {
int itemType = getItemViewType(position);
if (NavigationDrawerItem.TYPE_TITLE == itemType) {
convertView = View.inflate(getContext(), R.layout.item_title_navigation_drawer, null);
} else if (NavigationDrawerItem.TYPE_ITEM_UNDER_TITLE == itemType) {
convertView = View.inflate(getContext(), R.layout.item_under_title_navigation_drawer, null);
} else {
Log.e(TAG, "Returning default title view - Invalid drawer item type" + itemType);
convertView = View.inflate(getContext(), R.layout.item_title_navigation_drawer, null);
}
}
TextView tv = (TextView) convertView.findViewById(R.id.text);
tv.setText(getContext().getString(getItem(position).stringRes));
return convertView;
}
#Override
public int getItemViewType(int position) {
return getItem(position).type;
}
#Override
public int getViewTypeCount() {
return NavigationDrawerItem.NUMBER_OF_ITEM_TYPES;
}
#Override
public boolean isEnabled(int position) {
return NavigationDrawerItem.isItemClickable(getItemViewType(position));
}
}
And the NavigationDrawerItem class:
public final class NavigationDrawerItem {
private static final String TAG = "NavigationDrawerItem";
// Types must have numbers from 0 to n without gaps.
public static final int TYPE_TITLE = 0;// nonclickable
public static final int TYPE_ITEM_UNDER_TITLE = 1;// clickabel
public static final int NUMBER_OF_ITEM_TYPES = 2;
public final int action;
public final String argument;
public final int type;
//Constructors etc.
public static final boolean isItemClickable(int itemType) {
if (TYPE_TITLE == itemType) {
return false;
} else if (TYPE_ITEM_UNDER_TITLE == itemType) {
return true;
} else {
Log.e(TAG, "Invalid item type " + itemType);
return false;
}
}
}

Get text content in EditText ListView after click button issue

I have a Listview of EditText and I need to get the String values of each edited row when I click a confirm button, but I don't know how.
I have tried to adapt some sample with no success ( I get always the default values and not the edited values).
My attempt is this
public class MyActivity extends Activity {
static int nItems;
ImageButton confirmButton;
ListView myList;
ListViewAdapterEditText adapterG1, adapterG2, adapterG3;
#Override
public void onCreate(Bundle savedInstanceState) {
.....
myList = (ListView) findViewById(R.id.listaG1);
myList.setItemsCanFocus(true);
adapterG1 = new ListViewAdapterEditText();
myList.setAdapter(adapterG1);
}
OnClickListener mConfirmButtonListener = new OnClickListener() {
public void onClick(View v) {
ArrayList a1 = adapterG1.getItems();
for (int i = 0; i < nItems; i++) {
System.out.println(a1.get(i)
+ "\n\n");
}
};
public class ListViewAdapterEditText extends BaseAdapter {
private LayoutInflater mInflater;
public ArrayList myItems = new ArrayList();
ListItem listItem;
public ListViewAdapterEditText() {
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (int i = 0; i < nItems; i++) {
listItem = new ListItem();
listItem.caption = "Caption" + i;
myItems.add(listItem);
}
notifyDataSetChanged();
}
public int getCount() {
return myItems.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public ArrayList<String> getItems() {
ArrayList<String> items = new ArrayList<String>();
for (int i = 0; i < nItems; i++) {
ListItem li = (ListItem) myItems.get(i);
items.add(li.getCaption());
}
return items;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.list_item_row,
null);
holder.caption = (EditText) convertView
.findViewById(R.id.ItemCaption);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// Fill EditText with the value you have in data source
holder.caption.setText(((ListItem) myItems.get(position)).caption);
// holder.caption.setText(myItems.get(position).caption);
holder.caption.setId(position);
// we need to update adapter once we finish with editing
holder.caption
.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
final int position = v.getId();
final EditText Caption = (EditText) v;
((ListItem) myItems.get(position)).caption = Caption
.getText().toString();
}
}
});
return convertView;
}
class ViewHolder {
EditText caption;
}
class ListItem {
String caption;
public String getCaption() {
return caption;
}
}
}
}
Could someone help me to solve this problem?
Are you sure your OnFocusChangeListener is called? If you edit the text in EditText then tap the confirm button, this listener will not be called in touch mode since the focus is still on the EditText.
Update: Consider the situation you edited the text in a EditText while didn't confirm and scrolled the ListView so that the item view is recycled, I'm not sure what is your preferred way, but if you want store the edited data, you can use setRecyclerListener(android.widget.AbsListView.RecyclerListener) to get notified when a item view is recycled so you can saved the edit result. To save the result of EditText showing on screen, you use methods like getChildAt to get item views visible on screen then get the EditText's text.
Update2: Another better and clean way is use TextWatcher and addTextChangeListener, this will notifies you when the text in EditText is changed.
Update3: I just write the following sample and test it, and it works on my phone. :)
Update4: I removed the previous code cause its performance is bad and creates a lot objects, you can check the following full sample instead:
Activity code :
package com.example.asynctasktest;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListView;
/**
* #author Daniel Chow
*
* May 26, 2013 12:57:49 AM
*/
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView) findViewById(R.id.listview);
final TestAdapter adapter = new TestAdapter(this);
listView.setAdapter(adapter);
Button confirmButton = (Button) findViewById(R.id.confirm_button);
confirmButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
List<String> items = adapter.getItems();
for (int i = 0, n = items.size(); i < n; i++) {
Log.e("", items.get(i));
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Adapter code:
/**
*
*/
package com.example.asynctasktest;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.EditText;
/**
* #author Daniel Chow
*
* May 26, 2013 1:13:02 AM */
public class TestAdapter extends BaseAdapter {
private List<String> items = new ArrayList<String>();
private Context context;
public TestAdapter(Context context) {
this.context = context;
for (int i = 0; i < 12; i++) {
items.add("caption " + i);
}
}
public List<String> getItems() {
return new ArrayList<String>(items);
}
#Override
public int getCount() {
return 12;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = new EditText(context);
holder = new ViewHolder();
holder.editText = (EditText) convertView;
holder.watcher = new EditTextWatcher();
holder.editText.addTextChangedListener(holder.watcher);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.watcher.setTarget(position);
holder.editText.setText(items.get(position));
return convertView;
}
private class EditTextWatcher implements TextWatcher {
private int target;
public void setTarget(int target) {
this.target = target;
}
#Override
public void afterTextChanged(Editable s) {
items.set(target, s.toString());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
}
private static class ViewHolder {
EditText editText;
EditTextWatcher watcher;
}
}
I usually follow a simpler technique
public class Item_Adapter extends BaseAdapter {
private String[] Val;
public Item_Adapter () {
Val= new String[nItems];
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
///bla bla
holder.caption
.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
final int position = v.getId();
final EditText Caption = (EditText) v;
((ListItem) myItems.get(position)).caption = Caption
.getText().toString();
Val[position]= Caption
.getText().toString();
}
}
});
///bla bla
return convertView;
}
/////most important returning your array so you can use it in the Activity
public String[] getVal() {
return Val;
}

Categories

Resources