I implemented a listview inside DialogFragment. Each item has a textview with a selector to simulate a radio group with option to select only one item at a time.
The problem is when the user clicks on an item I am updating the data on the adapter then calling to notifyDataSetChanged() and calling dialog.dismiss().
The user don`t see the selection of item before the dialog is dismissed.
I fixed this by adding postdelay to dismiss functionality, Maybe there is a better solution for this problem?
This is my code:
public class SettingsPopupAdapter extends BaseAdapter
{
private List<SettingsItem> _data;
private Context _con;
public SettingsPopupAdapter(Context con, List<SettingsItem> data)
{
_con = con;
_data = data;
}
#Override
public int getCount()
{
return _data.size();
}
#Override
public SettingsItem getItem(int position)
{
return _data.get(position);
}
#Override
public long getItemId(int position)
{
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder;
if (convertView == null)
{
holder = new ViewHolder();
convertView = LayoutInflater.from(_con).inflate(R.layout.settings_popup_checkbox_row_item, parent, false);
holder._text = (TextView) convertView.findViewById(R.id.option_text);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
SettingsItem item = getItem(position);
holder._text.setText(item.getItemLabel());
holder._text.setSelected(item.isSelected());
return convertView;
}
private static class ViewHolder
{
public TextView _text;
}
public String getSelectedItem()
{
String selectedItem = null;
for (SettingsItem item : _data)
{
if (item.isSelected())
{
selectedItem = item.getItemLabel();
break;
}
}
return selectedItem;
}
public List<String> getSelectedItems()
{
List<String> selectedOptions = new ArrayList<String>();
for (SettingsItem item : _data)
{
if (item.isSelected())
{
selectedOptions.add(item.getItemLabel());
}
}
return selectedOptions;
}
public void setData(ArrayList<SettingsItem> items)
{
_data = items;
notifyDataSetChanged();
}
}
This code is in the fragment from where I am opening the dialog :
private SettingsPopupAdapte _modAdapter;
private ArrayList<SettingsItem> _items;
_modAdapter = new SettingsPopupAdapter(getActivity(),_items);
_modificationListView.setAdapter(_modAdapter);
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
String selectedItem = _items.get(position).getItemLabel();
selectExclusiveList(selectedItem);
Bundle b = new Bundle();
b.putInt(Consts.MODIFICATION_TYPE_KEY, _type);
b.putString(Consts.RESPONSE_DATA_KEY,selectedItem);
_listener.onRetrieveData(b);
//show the change before the dialog dismissed
getView().postDelayed(new Runnable()
{
#Override
public void run()
{
dismiss();
}
},200);
}
private void selectExclusiveList(String selectedItem)
{
for (SettingsItem item : _items)
{
item.setSelected(false);
if (item.getItemLabel().equals(selectedItem))
{
item.setSelected(true);
}
}
_modAdapter.setData(_items);
}
Related
I want to share the listview items.Listview contains many items.But when i select third or any item other than the first item for sharing, it is taking only the first item for sharing.I have attached my code.Please help me to solve this.
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.share:
SparseBooleanArray selectedshare = adapter.getSelectedIds();
for (int i = (selectedshare.size() - 1); i >= 0; i--) {
if (selectedshare.valueAt(i)) {
val = list.get(i).getId();
System.out.println("idddddddddd"+val);
date = list.get(i).getDate();
System.out.println("dateeee"+date);
title = list.get(i).getTitle();
System.out.println("titleeee"+title);
content = list.get(i).getContent();
System.out.println("contenttttt"+content);
shareIt();
}
}
return true;
///////for sharing///////
default:
return false;
}
}
////here is the function//////
private void shareIt() {
//sharing implementation here
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "All memories");
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Date :"+date +"\n"+"Title :"+title+"\n"+"Content :"+ content);
startActivity(Intent.createChooser(sharingIntent, "Share via"));
}
#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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
Here is my adapter code:
I did nothing in adapter class for sharing.
public class ListViewAdapter extends BaseAdapter {
public ArrayList<all_memories_getter_setter>list;
Activity activity;
/////**///// multiple delete
private SparseBooleanArray mSelectedItemsIds;
public ListViewAdapter(Activity activity,
ArrayList<all_memories_getter_setter>list)
{
super();
mSelectedItemsIds= new SparseBooleanArray();
this.activity=activity;
this.list=list;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int position) {
return list.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
/////**/////// for multiple delete
public void remove(all_memories_getter_setter object){
list.remove(object);
notifyDataSetChanged();
}
public List<all_memories_getter_setter> getall_memories_getter_setter(){
return list;
}
public void toggleSelection(int position){
selectView(position, !mSelectedItemsIds.get(position));
}
public void removeSelection(){
mSelectedItemsIds = new SparseBooleanArray();
notifyDataSetChanged();
}
public void selectView(int position , boolean value){
if(value){
mSelectedItemsIds.put(position, value);
}else{
mSelectedItemsIds.delete(position);
notifyDataSetChanged();
}
}
public int getSelectedCount(){
return mSelectedItemsIds.size();
}
public SparseBooleanArray getSelectedIds(){
return mSelectedItemsIds;
}
public class Viewholder
{
TextView txtFirst;
TextView txtSecond;
TextView txtThird;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Viewholder holder;
LayoutInflater inflater = activity.getLayoutInflater();
if (convertView == null) {
convertView =
inflater.inflate(R.layout.activity_all_memories_listview, null);
holder = new Viewholder();
holder.txtFirst = (TextView)
convertView.findViewById(R.id.list_date);
holder.txtSecond = (TextView)
convertView.findViewById(R.id.list_title);
holder.txtThird = (TextView)
convertView.findViewById(R.id.list_content);
convertView.setTag(holder);
} else {
holder = (Viewholder) convertView.getTag();
}
holder.txtFirst.setText("" + list.get(position).getDate());
holder.txtSecond.setText("" + list.get(position).getTitle());
holder.txtThird.setText("" + list.get(position).getContent());
return convertView;
}
}
Please follow this steps to share the listview items content to other apps or within app
you can write your own method inside the getview() method of ListviewAdapter Class
Ex :
public class ListViewTestFiveActivity extends Activity{
private ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_view_test_five);
init();
}
private void init() {
listView = (ListView)findViewById(R.id.ListViewTestFiveActivity_listView);
ArrayList<Item> items = new ArrayList<>();
for (int i = 0; i < 15; i++) {
Item item = new Item();
item.setCount(i);
items.add(item);
}
MyAdapter adapter = new MyAdapter(getApplicationContext(), R.layout.single_item_listview_five, items);
listView.setAdapter(adapter);
}
private class MyAdapter extends ArrayAdapter{
private ArrayList<Item> items;
private Context a_context;
private LayoutInflater a_layoutInflater;
public MyAdapter(Context context, int resource, ArrayList<Item> items) {
super(context, resource, items);
this.a_context = context;
this.items = items;
a_layoutInflater = LayoutInflater.from(this.a_context);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder = null;
if (row == null) {
row = a_layoutInflater.inflate(R.layout.single_item_listview_five, parent, false);
holder = new ViewHolder();
holder.share = (Button) row.findViewById(R.id.ListViewTestFiveActivity_share_button);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
final Item item = items.get(position);
holder.share.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Here you can write your own code to share the data, item has the data which you want to share
}
});
return row;
}
private class ViewHolder{
Button share;
}
}
private class Item {
int count;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
}
Let me know if it works you or not
I have a ListView with a gridview for each item:
So when I press the add button I need to add a new item to the gridView(scenesGridViewAdapter) adapter, but when I press the add button always is added to the last gridview.
public class ScenesAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<SceneObject> sceneObjects;
private ArrayList<ScenesGridViewAdapter> scenesGridViewAdapters;
private ScenesGridViewAdapter scenesGridViewAdapter;
public ScenesAdapter(Activity activity, ArrayList<SceneObject> sceneObjects) {
this.activity = activity;
this.sceneObjects = sceneObjects;
this.scenesGridViewAdapters = new ArrayList<>();
}
#Override
public int getCount() {
return this.sceneObjects.size();
}
#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, final ViewGroup parent) {
final ViewHolder viewHolder;
if (convertView == null) {
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_scenes_item, null);
viewHolder = new ViewHolder();
viewHolder.tvStepIndex = (TextView) convertView.findViewById(R.id.tv_scene_index);
viewHolder.bmb1 = (BoomMenuButton) convertView.findViewById(R.id.bmb_open_item_menu);
viewHolder.scenesGridView = (ScenesGridView)convertView.findViewById(R.id.gv_scene_items) ;
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
int index = position + 1;
viewHolder.tvStepIndex.setText("" + index);
scenesGridViewAdapter = new
ScenesGridViewAdapter(this.activity, sceneObjects.get(position).getScenes());
viewHolder.scenesGridView.setAdapter(scenesGridViewAdapter);
viewHolder.bmb1.clearBuilders();
viewHolder.bmb1.addBuilder(BuilderManager.getTextOutsideCircleButtonBuilder("Añadir acción"));
viewHolder.bmb1.addBuilder(BuilderManager.getTextOutsideCircleButtonBuilder("Eliminar paso"));
viewHolder.bmb1.setOnBoomListener(new OnBoomListener() {
#Override
public void onClicked(int index, BoomButton boomButton) {
switch (index){
case 0:
scenesGridViewAdapter.addNew("hello");
notifyDataSetChanged();
break;
case 1:
sceneObjects.remove(position);
notifyDataSetChanged();
break;
}
}
#Override
public void onBackgroundClick() {
}
#Override
public void onBoomWillHide() {
}
#Override
public void onBoomDidHide() {
}
#Override
public void onBoomWillShow() {
}
#Override
public void onBoomDidShow() {
}
});
return convertView;
}
class ViewHolder {
TextView tvStepIndex;
ScenesGridView scenesGridView;
BoomMenuButton bmb1;
}
public void addNewScene(SceneObject sceneObject){
sceneObjects.add(sceneObject);
this.notifyDataSetChanged();
}
}
Can you please help me to add and item to the gridview position?
Thank you.
I have a listview . When clicked on listitem it opens up a new activity which contains a button(add to fav) which adds the opened list item to my favorites activity(using shared preference) and should change the color of the heart image in listitem from grey to red indicating its in favorites.
Adding the listitem to favorites work fine but the heart image is not changing from grey to red unless it is scrolled out of the user's view from the screen and scrolled back to it again.
To better understand my problem look at this video
I want the changing of the image instantaneously
By the way to convert the listitem object to jsonString and pass it via intent i used jacksons library
The code i use
onitemclicklistener of my list fragment
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
ObjectMapper mapper = new ObjectMapper();
Product pro = productListAdapter.getItem(position);
try
{
String jsonInString = mapper.writeValueAsString(pro);
Intent intent = new Intent(activity.getApplicationContext(), SingleItemView.class);
intent.putExtra("selected item", jsonInString);
startActivity(intent);
}
catch (JsonProcessingException e)
{}
}
my adapter for the list
public class ProductListAdapter extends ArrayAdapter<Product> {
private Context context;
List<Product> products;
SharedPreference sharedPreference;
public ProductListAdapter(Context context, List<Product> products) {
super(context, R.layout.product_list_item, products);
this.context = context;
this.products = products;
sharedPreference = new SharedPreference();
}
private class ViewHolder {
TextView productNameTxt;
TextView productDescTxt;
TextView productPriceTxt;
ImageView favoriteImg;
}
#Override
public int getCount() {
return products.size();
}
#Override
public Product getItem(int position) {
return products.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.product_list_item, null);
holder = new ViewHolder();
holder.productNameTxt = (TextView) convertView
.findViewById(R.id.txt_pdt_name);
holder.productDescTxt = (TextView) convertView
.findViewById(R.id.txt_pdt_desc);
holder.productPriceTxt = (TextView) convertView
.findViewById(R.id.txt_pdt_price);
holder.favoriteImg = (ImageView) convertView
.findViewById(R.id.imgbtn_favorite);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Product product = (Product) getItem(position);
holder.productNameTxt.setText(product.getName());
holder.productDescTxt.setText(product.getDescription());
holder.productPriceTxt.setText(product.getPrice() + "");
/*If a product exists in shared preferences then set heart_red drawable
* and set a tag*/
if (checkFavoriteItem(product)) {
holder.favoriteImg.setImageResource(R.drawable.heart_red);
holder.favoriteImg.setTag("red");
} else {
holder.favoriteImg.setImageResource(R.drawable.heart_grey);
holder.favoriteImg.setTag("grey");
}
return convertView;
}
/*Checks whether a particular product exists in SharedPreferences*/
public boolean checkFavoriteItem(Product checkProduct) {
boolean check = false;
List<Product> favorites = sharedPreference.getFavorites(context);
if (favorites != null) {
for (Product product : favorites) {
if (product.equals(checkProduct)) {
check = true;
break;
}
}
}
return check;
}
#Override
public void add(Product product) {
super.add(product);
products.add(product);
notifyDataSetChanged();
}
#Override
public void remove(Product product) {
super.remove(product);
products.remove(product);
notifyDataSetChanged();
}
}
singleitem activity
public class SingleItemView extends Activity
{
ProductListAdapter padaptr;
SharedPreference sharedPreference;
List<Product> products = null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO: Implement this method
super.onCreate(savedInstanceState);
setContentView(R.layout.singleitem);
sharedPreference = new SharedPreference();
padaptr = new ProductListAdapter(SingleItemView.this, products);
Button btn = (Button) findViewById(R.id.singleitemButton1);
btn.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v){
products=new ArrayList<Product>();
Bundle extras = getIntent().getExtras();
String jsonObj = extras.getString("selected item");
ObjectMapper mapper = new ObjectMapper();
try
{
Product pro = mapper.readValue(jsonObj, Product.class);
if (checkFavoriteItem(pro)) {
sharedPreference.removeFavorite(SingleItemView.this, pro);
Toast.makeText(SingleItemView.this,
SingleItemView.this.getResources().getString(R.string.remove_favr),
Toast.LENGTH_SHORT).show();
padaptr.notifyDataSetChanged();
} else {
sharedPreference.addFavorite(SingleItemView.this, pro);
Toast.makeText(SingleItemView.this,
SingleItemView.this.getResources().getString(R.string.add_favr),
Toast.LENGTH_SHORT).show();
padaptr.notifyDataSetChanged();
}
}
catch (IOException e)
{};
}
private boolean checkFavoriteItem(Product checkProduct) {
boolean check = false;
List<Product> favorites = sharedPreference.getFavorites(getApplicationContext());
if (favorites != null) {
for (Product product : favorites) {
if (product.equals(checkProduct)) {
check = true;
break;
}
}
}
return check;
}
});
}
}
You need to notify your adapter about the changes, when you came back to the fragment/activity.
Use startActivityForResult() to start your second activity:
Intent intent = new Intent(activity.getApplicationContext(), SingleItemView.class);
intent.putExtra("selected item", jsonInString);
startActivityForResult(intent, 1);
Then override onActivityResult() method to handle the call back, and notify your adapter with notifyDataSetChanged():
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
productListAdapter.notifyDataSetChanged();
}
}
I'd like to achieve the behaviour you've attached in your video with adding a toggleSelection with my List Adapter. Here's I'm attaching an working adapter which will toggle the list item background when clicked. This might be modified to serve your purpose.
public class ToggleSelectionListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Cursor mCursor;
private SparseBooleanArray selectedItems;
public ToggleSelectionListAdapter(Cursor cursor) {
mCursor = cursor;
selectedItems = new SparseBooleanArray();
}
public void toggleSelection(int pos) {
if (selectedItems.get(pos, false)) {
selectedItems.delete(pos);
} else {
selectedItems.put(pos, true);
}
notifyItemChanged(pos);
}
public int getSelectedItemCount() {
return selectedItems.size();
}
public void clearSelections() {
selectedItems.clear();
notifyDataSetChanged();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(final View itemView) {
super(itemView);
// Initialize your items of each row here
}
public void bindView(int pos) {
try {
if (mCursor.isClosed())
return;
mCursor.moveToPosition(pos);
// Maintain a checked item list so that you can have a track if the item is clicked or not
if (checkedItems.contains(number) itemView.setBackgroundResource(R.drawable.background_selected);
else itemView.setBackgroundResource(R.drawable.background_normal);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (checkedItems.contains(number)) {
checkedItems.remove(number);
} else {
checkedItems.add(number);
}
// Get the index of which item should toggle the background
int idx = mRecyclerView.getChildAdapterPosition(v);
toggleSelection(idx);
}
}
});
}
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_row, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof ViewHolder) {
ViewHolder vh = (ViewHolder) holder;
vh.bindView(position);
}
}
#Override
public int getItemCount() {
if (mCursor == null) {
return 0;
}
int n = mCursor.getCount();
return n;
}
#Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
synchronized public void swapCursor(Cursor cursor) {
mCursor = cursor;
notifyDataSetChanged();
}
}
Hi i'm trying to do list view with drop down detailed view. For example see this Image 1. When we click any list view then it display the detailed view (with respect to the list view)like Image 2. This detailed view not like expandable list view or spinner. Please help me to do this
Please checkout this github i just setup https://github.com/lt-tibs1984/ExpandableListView
The idea is hide and show the view using visibility, here is some code illustrating the point:
First setup your Item class or whatever object you want to use (simple pojo implementing Parcelable)
public class Item implements Parcelable{
public String title;
public String description;
public boolean isExpanded;
public Item(){}
public Item(Parcel in){
title = in.readString();
description = in.readString();
isExpanded = in.readInt() == 1;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(title);
dest.writeString(description);
dest.writeInt(isExpanded ? 1 : 0);
}
public static final Parcelable.Creator<Item> CREATOR = new Parcelable.Creator<Item>(){
#Override
public Item createFromParcel(Parcel source) {
return new Item(source);
}
#Override
public Item[] newArray(int size) {
return new Item[size];
}
};
}
then create your adapter:
public class ExpandableAdapter extends BaseAdapter{
List<Item> items;
Context context;
public class Row{
AppCompatTextView mTvTitle;
AppCompatTextView mTvDescription;
FrameLayout mFlWrapper;
ImageView mIvArrow;
}
public ExpandableAdapter(Context context, List<Item> items){
this.items = items;
this.context = context;
}
#Override
public int getCount() {
return items.size();
}
#Override
public Object getItem(int position) {
return items.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Row theRow;
if(convertView == null){
theRow = new Row();
convertView = LayoutInflater.from(context).inflate(R.layout.row_item, parent, false);
theRow.mFlWrapper = (FrameLayout) convertView.findViewById(R.id.fl_wrapper);
theRow.mTvTitle = (AppCompatTextView) convertView.findViewById(R.id.tv_title);
theRow.mTvDescription = (AppCompatTextView) convertView.findViewById(R.id.tv_description);
theRow.mIvArrow = (ImageView) convertView.findViewById(R.id.iv_arrow);
convertView.setTag(theRow);
}else{
theRow = (Row) convertView.getTag();
}
// Update the View
Item item = items.get(position);
if(item.isExpanded){
theRow.mFlWrapper.setVisibility(View.VISIBLE);
theRow.mIvArrow.setRotation(180f);
}else{
theRow.mFlWrapper.setVisibility(View.GONE);
theRow.mIvArrow.setRotation(0f);
}
theRow.mTvTitle.setText(item.title);
theRow.mTvDescription.setText(item.description);
// return the view
return convertView;
}
}
finally in your Activity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lvItems = (ListView) findViewById(R.id.lv_items);
ExpandableAdapter adapter = getAdapter();
lvItems.setAdapter(adapter);
lvItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ExpandableAdapter adapter = (ExpandableAdapter) parent.getAdapter();
Item item = (Item) adapter.getItem(position);
if(item != null){
if(item.isExpanded){
item.isExpanded = false;
}else{
item.isExpanded = true;
}
}
adapter.notifyDataSetChanged();
}
});
}
private ExpandableAdapter getAdapter(){
List<Item> items = new ArrayList<>();
for(int i = 0; i < 50; i++){
Item item = new Item();
item.title = "Title Item " + i;
item.description = "Description for Title Item "+ i;
item.isExpanded = false;
items.add(item);
}
return new ExpandableAdapter(this, items);
}
}
Special thanks to "inner_class7": According to the "inner_class7" i got the answer but by using his code i have to achieve two requirements
Requirement 1: When we clicking on the description the expanded view is closing but i don't want to close the view
Requirement 2: I want to close the previous view (if exists) when extending the new view
To achieve above two requirements, update "inner_class7" code according to the below steps
Step 1: Create Global.java
public class Global {
public static Item itemGlobal;
}
Step 2: Update MainActivity.java
import static com.app.listviewdrop.Global.itemGlobal;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_view_drop);
ListView lvItems = (ListView) findViewById(R.id.lv_items);
ExpandableAdapter adapter = getAdapter();
lvItems.setAdapter(adapter);
lvItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ExpandableAdapter adapter = (ExpandableAdapter) parent.getAdapter();
Item item = (Item) adapter.getItem(position);
if(item != null){
if(item.isExpanded){
item.isExpanded = false;
}else{
item.isExpanded = true;
itemGlobal = (Item)adapter.getItem(position);
}
}
adapter.notifyDataSetChanged();
}
});
}
private ExpandableAdapter getAdapter(){
List<Item> items = new ArrayList<Item>();
for(int i = 0; i < 50; i++){
Item item = new Item();
item.title = "Title Item " + i;
item.description = "Description for Title Item "+ i;
item.isExpanded = false;
items.add(item);
}
return new ExpandableAdapter(this, items);
}
}
Step3: Update ExpandableAdapter.java
import static com.YOUR PACKAGE NAME.itemGlobal;
public class ExpandableAdapter extends BaseAdapter {
List<Item> items;
Context context;
// List<Item> list = new ArrayList<Item>();
public class Row {
AppCompatTextView mTvTitle;
AppCompatTextView mTvDescription;
FrameLayout mFlWrapper;
ImageView mIvArrow;
}
public ExpandableAdapter(Context context, List<Item> items) {
this.items = items;
this.context = context;
}
#Override
public int getCount() {
return items.size();
}
#Override
public Object getItem(int position) {
return items.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Row theRow;
if (convertView == null) {
theRow = new Row();
convertView = LayoutInflater.from(context).inflate(R.layout.row_item, parent, false);
theRow.mFlWrapper = (FrameLayout) convertView.findViewById(R.id.fl_wrapper);
theRow.mTvTitle = (AppCompatTextView) convertView.findViewById(R.id.tv_title);
theRow.mTvDescription = (AppCompatTextView) convertView.findViewById(R.id.tv_description);
theRow.mIvArrow = (ImageView) convertView.findViewById(R.id.iv_arrow);
convertView.setTag(theRow);
theRow.mFlWrapper.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
}
});
} else {
theRow = (Row) convertView.getTag();
}
// Update the View
Item item = items.get(position);
if (item.isExpanded) {
if(item == itemGlobal){
theRow.mFlWrapper.setVisibility(View.VISIBLE);
theRow.mIvArrow.setRotation(180f);
}else {
theRow.mFlWrapper.setVisibility(View.GONE);
theRow.mIvArrow.setRotation(0f);
item.isExpanded = false;
}
} else {
theRow.mFlWrapper.setVisibility(View.GONE);
theRow.mIvArrow.setRotation(0f);
}
theRow.mTvTitle.setText(item.title);
theRow.mTvDescription.setText(item.description);
// return the view
return convertView;
}
}
I achieved these requirements only the help of "inner_class7". Many many thanks to "inner_class7"
I'm using navigation drawer. Navigation Drawer contains elements/items (Like: feedback, report, settings, refresh) in it. When I clicked on an Item then according to selected option UI will get updated.
Problem is that: I selected an Item from Navigation drawer, then UI get updated. If again I selected same option then again all methods for updating UI get called.
What I want is, If user clicked again on same Item in navigation drawer, then background methods should not get called.
I tries to set clickable property false, but with that items become non clickable. I'm not able to select the item.
Suppose I selected Feedback option, then next time when I again open the drawer then feedback option should not get selected. Means, consecutively user should not able to select same option.
Added Code:: Adapter Class:
public class NavDrawerAdapter extends ArrayAdapter<NavDrawerItem> {
private LayoutInflater inflater;
public NavDrawerAdapter(Context context, int textViewResourceId,
NavDrawerItem[] objects) {
super(context, textViewResourceId, objects);
this.inflater = LayoutInflater.from(context);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
NavDrawerItem menuItem = this.getItem(position);
if (menuItem.getType() == NavMenuItem.ITEM_TYPE) {
view = getItemView(convertView, parent, menuItem);
} else {
view = getSectionView(convertView, parent, menuItem);
}
return view;
}
public View getItemView(View convertView, ViewGroup parentView,
NavDrawerItem navDrawerItem) {
NavMenuItem menuItem = (NavMenuItem) navDrawerItem;
NavMenuItemHolder navMenuItemHolder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.navdrawer_item, parentView,
false);
TextView labelView = (TextView) convertView
.findViewById(R.id.navmenuitem_label);
ImageView iconView = (ImageView) convertView
.findViewById(R.id.navmenuitem_icon);
navMenuItemHolder = new NavMenuItemHolder();
navMenuItemHolder.labelView = labelView;
navMenuItemHolder.iconView = iconView;
convertView.setTag(navMenuItemHolder);
}
if (navMenuItemHolder == null) {
navMenuItemHolder = (NavMenuItemHolder) convertView.getTag();
}
navMenuItemHolder.labelView.setText(menuItem.getLabel());
navMenuItemHolder.iconView.setImageResource(menuItem.getIcon());
return convertView;
}
public View getSectionView(View convertView, ViewGroup parentView,
NavDrawerItem navDrawerItem) {
NavMenuSection menuSection = (NavMenuSection) navDrawerItem;
NavMenuSectionHolder navMenuItemHolder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.navdrawer_section,
parentView, false);
TextView labelView = (TextView) convertView
.findViewById(R.id.navmenusection_label);
navMenuItemHolder = new NavMenuSectionHolder();
navMenuItemHolder.labelView = labelView;
convertView.setTag(navMenuItemHolder);
}
if (navMenuItemHolder == null) {
navMenuItemHolder = (NavMenuSectionHolder) convertView.getTag();
}
navMenuItemHolder.labelView.setText(menuSection.getLabel());
return convertView;
}
#Override
public int getViewTypeCount() {
return 2;
}
#Override
public int getItemViewType(int position) {
return this.getItem(position).getType();
}
#Override
public boolean isEnabled(int position) {
return getItem(position).isEnabled();
}
private static class NavMenuItemHolder {
private TextView labelView;
private ImageView iconView;
}
private class NavMenuSectionHolder {
private TextView labelView;
}
}
Activity Class::
public class NavDrawerActivity extends AbstractNavDrawerActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if ( savedInstanceState == null ) {
FragmentManager fragmentManager=getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, new MainFragment()).commit();
}
}
#Override
protected NavDrawerActivityConfiguration getNavDrawerConfiguration() {
NavDrawerItem[] menu = new NavDrawerItem[] {
NavMenuSection.create( 100, "Logged in user details"),
//NavMenuItem.create(101,"List/Detail (Fragment)", "navdrawer_friends", true, this),
//NavMenuItem.create(102, "Airport (AsyncTask)", "navdrawer_airport", false, this),
//NavMenuSection.create(200, "General"),
NavMenuItem.create(202, getResources().getString(R.string.nav_drawer_item_reports), (R.drawable.drawer_shadow), false, this),
NavMenuItem.create(203, getResources().getString(R.string.nav_drawer_item_feedback), (R.drawable.drawer_shadow), false, this),
NavMenuItem.create(204, getResources().getString(R.string.nav_drawer_item_settings), (R.drawable.drawer_shadow), false, this)};
NavDrawerActivityConfiguration navDrawerActivityConfiguration = new NavDrawerActivityConfiguration();
navDrawerActivityConfiguration.setMainLayout(R.layout.activity_nav_drawer);
navDrawerActivityConfiguration.setDrawerLayoutId(R.id.drawer_layout);
navDrawerActivityConfiguration.setLeftDrawerId(R.id.left_drawer);
navDrawerActivityConfiguration.setNavItems(menu);
navDrawerActivityConfiguration.setDrawerShadow(R.drawable.drawer_shadow);
navDrawerActivityConfiguration.setDrawerOpenDesc(R.string.drawer_open);
navDrawerActivityConfiguration.setDrawerCloseDesc(R.string.drawer_close);
navDrawerActivityConfiguration.setBaseAdapter(
new NavDrawerAdapter(this, R.layout.navdrawer_item, menu ));
return navDrawerActivityConfiguration;
}
#Override
protected void onNavItemSelected(int id) {
switch ((int)id) {
case 202:
getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, new MainFragment()).commit();
break;
case 203:
//getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, new AirportFragment()).commit();
Toast.makeText(this, "Friend", Toast.LENGTH_SHORT);
break;
}
}
}
MenuItem interface::
public interface NavDrawerItem {
public int getId();
public String getLabel();
public int getType();
public boolean isEnabled();
public boolean updateActionBarTitle();
}
Implementated Class:
public class NavMenuItem implements NavDrawerItem {
public static final int ITEM_TYPE = 1 ;
private int id ;
private String label ;
private int icon ;
private boolean updateActionBarTitle ;
private NavMenuItem() {
}
public static NavMenuItem create( int id, String label, int icon, boolean updateActionBarTitle, Context context ) {
NavMenuItem item = new NavMenuItem();
item.setId(id);
item.setLabel(label);
item.setIcon(icon);
item.setUpdateActionBarTitle(updateActionBarTitle);
return item;
}
#Override
public int getType() {
return ITEM_TYPE;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public int getIcon() {
return icon;
}
public void setIcon(int icon) {
this.icon = icon;
}
#Override
public boolean isEnabled() {
return true;
}
#Override
public boolean updateActionBarTitle() {
return this.updateActionBarTitle;
}
public void setUpdateActionBarTitle(boolean updateActionBarTitle) {
this.updateActionBarTitle = updateActionBarTitle;
}
}
Added code for drawer listener :
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
}
I got the answer. Need to maintain lastClicked position. if lastclicked element is same as current clicked element, then no need to do anything. If current position is different then update the lastClicked with current position.
private static int lastClicked = 0;
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(lastClicked != position){
selectItem(position);
}
lastClicked = position;
}
}