I have a PopupWindow that contains a RecyclerView. The RecyclerView's last element is a button that adds a new item to the end of the adapter's list when clicked.
The problem:
During the first time my PopupWindow has been launched the button successfully adds new items to the RecyclerView with notifyItemInserted(dataSize - 1) when clicked, but the RecyclerView doesn't update and show them. If I close and re-open the PopupWindow however, the items previously added are properly shown in the RecyclerView and it properly updates and animates new items being added to its adapter.
The Question: I'm not sure why the RecyclerView doesn't refresh and show the newly added items on first run of the PopupWindow, but works perfectly from second run onward. How do I make it work during the first run of the PopupWindow?
P.S. Its worth noting that if I use notifyDataSetChanged() the RecyclerView works correctly (displays new items) even on first launch of the PopupWindow. I want to find a way to make notifyItemInserted() work however, because it has nice animations when new items are added.
UserChordsAdapter.java
public class UserChordsAdapter extends RecyclerView.Adapter<UserChordsAdapter.ChordViewHolder> {
private Context context;
private final ListItemClickListener mClickHandler;
private ArrayList<String> mChordData = new ArrayList<String>(); //contains all user created chords as comma delimited note #s
/**
* The interface that receives onClick messages.
*/
public interface ListItemClickListener {
void onListItemClick(int clickedItemIndex);
}
/**
*
* #param clickHandler The on-click handler for this adapter. This single handler is called
* when an item is clicked.
*/
public UserChordsAdapter(ListItemClickListener clickHandler) {
mClickHandler = clickHandler;
}
#Override
public ChordViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
context = parent.getContext();
int layoutIdForListItem = R.layout.user_chord_list_item;
int layoutIdForFooterItem = R.layout.user_chord_add_new;
LayoutInflater inflater = LayoutInflater.from(context);
boolean shouldAttachToParentImmediately = false;
View listItem;
ChordViewHolder viewHolder;
if (viewType == R.layout.user_chord_list_item) { //inflate chord item
listItem = inflater.inflate(layoutIdForListItem, parent, shouldAttachToParentImmediately);
viewHolder = new ChordViewHolder(listItem);
}
else { //inflate "+ Add new" button (last list item)
listItem = inflater.inflate(layoutIdForFooterItem, parent, shouldAttachToParentImmediately);
viewHolder = new ChordViewHolder(listItem);
}
return viewHolder;
}
#Override
public void onBindViewHolder(ChordViewHolder holder, int position) {
if (position == mChordData.size()){
holder.mAddChordButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
mChordData.add("1,30,40");
notifyItemInserted(mChordData.size()-1);
}
});
}
else {
holder.mChordName.setText("Chord " + Integer.toString(position));
}
}
#Override
public int getItemCount() {
if (mChordData == null){
return 1;
}
return mChordData.size() + 1; // +1 is for footer button (add new)
}
class ChordViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
// Will display which ViewHolder is displaying this data
TextView mChordName;
Button mAddChordButton;
/**
* Constructor for our ViewHolder. Within this constructor, we get a reference to our
* TextViews and set an onClickListener to listen for clicks. Those will be handled in the
* onClick method below.
*/
public ChordViewHolder(View itemView) {
super(itemView);
mAddChordButton = (Button) itemView.findViewById(R.id.button_add_new);
mChordName = (TextView) itemView.findViewById(R.id.tv_view_holder_instance);
itemView.setOnClickListener(this);
}
/**
* Called whenever a user clicks on an item in the list.
* #param v The View that was clicked
*/
#Override
public void onClick(View v) {
int clickedPosition = getAdapterPosition();
String chordData = mChordData.get(clickedPosition);
mClickHandler.onListItemClick(clickedPosition);
}
}
/**
* Distinguishes if view is a Chord list item or the last item in the list (add new chord)
* #param position
* #return
*/
#Override
public int getItemViewType(int position) {
return (position == mChordData.size()) ? R.layout.user_chord_add_new : R.layout.user_chord_list_item;
}}
FragmentChordMenu.java
public class FragmentChordMenu extends Fragment implements UserChordsAdapter.ListItemClickListener{
private FloatingActionButton mFAB;
private View mPopupView;
private PopupWindow mUserChordMenu;
private RecyclerView mUserChordsList;
private UserChordsAdapter mRecyclerViewAdapter;
private int numItems = 0; //TODO: dynamically calculate this as # of saved chords + 1(add new)
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mRecyclerViewAdapter = new UserChordsAdapter(this);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.menu_fragment_chord, container, false);
LayoutInflater layoutInflater = (LayoutInflater)getActivity().getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mPopupView = layoutInflater.inflate(R.layout.menu_popup_set_chords, null);
int menuWidth = (int)(MainActivity.getActualWidth()*.95);
int menuHeight = (int)(MainActivity.getActualHeight()*.90);
mUserChordMenu = new PopupWindow(mPopupView, menuWidth, menuHeight);
mUserChordMenu.setFocusable(true);
mFAB = (FloatingActionButton) v.findViewById(R.id.addChord);
mFAB.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
mUserChordMenu.showAtLocation(mPopupView, Gravity.CENTER, 10, 10);
mUserChordsList = (RecyclerView) mPopupView.findViewById(R.id.rv_userChords);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
mUserChordsList.setLayoutManager(layoutManager);
mUserChordsList.setAdapter(mRecyclerViewAdapter);
}
});
return v;
}
/**
* Called from UserChordsAdapter's onClick. Only fires on list item clicks, not the add new button
*
* */
#Override
public void onListItemClick(int clickedItemIndex) {
}}
The problem lies with the logic you use to update your views. Currently what you are saying is this, only notify my data when a view is drawn on the screen(OnBind). That is why it always work for the second try, because whenever a view is being drawn(swipe etc). that onBind method will be triggered.What you need to do is to create a method in the Adapter class, that replaces this logic.
holder.mAddChordButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
mChordData.add("1,30,40");
notifyItemInserted(mChordData.size()-1);
}
});
So create a method that adds item to the mChorData set object, then call notifyItemInserted(mChordData.size()-1); in that method. This will always update and notify the adapter of any changes, hence triggering redraw automatically.
First create a public method in UserChordsAdapter that accepts an mChordData for its paramter,then in that method call, notifyItemInserted(mChordData.size()-1);. Firstly you need to expose the clickListener outside of that adapter.
Related
I have a RecyclerView who play the recording when certain item is clicked. I want the behave when a user clicks on item1 that specific recording is playing and button View is changed which is working fine.
But at the same time when item1 recording is playing and user click on item2 then item1 row Button come back to its original position.
Below Image show the View when item1(Row 1) is clicked. (This is working fine)
I have also test this to control the View in inBindViewHolder method.But it is not working because whenever I clicked holder object control the View of current selected row only.
Below Code Section is placed in the ViewHolder
mPlayAudio.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
Log.d(TAG, "onClick: Present in onClick mPlayAudio");
if (listener != null)
{
final int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION)
{
// This section contain the code to play and stop
the audio
// Using below line I only able to change selected
// row button View not other row Button View
mPlayAudio.setImageResource(R.drawable.play);
}
}
}
});
I have also try this with in onBindViewHolder method but still not working.
Below Code added in onBindViewHolder
holder.mPlayAudio.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view)
{
// This section contain code to play and stop audio
//Using below statement I only able to change the
//visibility of current selected row View not others
holder.mPlayAudio.setImageResource(R.drawable.play);
}
}
So I finally was able to try this out on my own project.
Answer
In BindViewHolder, after you have made an item click, save the value of the position of that item. Then call notifyDataSetChanged inside the click event, which will refresh the adapter. Now it obtain your result, inside BindViewHolder have an if statement checking if that value should be set accordingly (or invisible), otherwise display as visible.
Example Code
public class SelectorAdapter extends RecyclerView.Adapter<SelectorAdapter.ItemHolder> implements View.OnClickListener {
private List itemList;
private int selectedKey;
public SelectorAdapter(List list) {
itemList = list;
}
#Override
public void onClick(View v) {
}
/* ViewHolder for each item */
class ItemHolder extends RecyclerView.ViewHolder {
//title
#BindView(R.id.selector_title)
TextView title;
#BindView(R.id.selector_layout)
LinearLayout selector;
ItemHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
#Override
public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_layout_selector, parent, false);
return new ItemHolder(itemView);
}
#Override
public void onBindViewHolder(ItemHolder holder, int position) {
String title = (String) itemList.get(position);
holder.title.setText(title);
if (position != selectedKey) {
holder.title.setBackgroundResource(R.drawable.selector);
} else {
holder.title.setBackgroundResource(R.drawable.selector_selected);
}
holder.itemView.setOnClickListener(v -> {
Timber.e("selected item: %s", position);
selectedKey = position;
notifyDataSetChanged();
});
}
#Override
public int getItemCount() {
Timber.e("itemCount: %s", itemList.size());
return itemList.size();
}
}
Here is my own project where when I select an item, it changes the background resource to selected, and then the rest are returned to the default state.
I have created a listview. Each item in list view has two UI elements. One is a textview and other is a number picker. Now the issue is that if i click on first number picker to change value, the fourth one also changes and vice versa. Here is my getview function
private class ViewHolder {
public TextView name;
public NumberPicker numberPicker;
public CustomListener listener;
}
public View getView(final int position, #Nullable View convertView, #NonNull final ViewGroup parent) {
ViewHolder holder;
View listItem = convertView;
currentCell=getItem(position);
currentCell.setPosition(position);
if (listItem == null) {
LayoutInflater inflater = LayoutInflater.from(mContext);
listItem = inflater.inflate(R.layout.organ_item, parent, false);
}
holder = new ViewHolder();
holder.name = (TextView) listItem.findViewById(R.id.organName);
holder.numberPicker = (NumberPicker)
listItem.findViewById(R.id.numberPicker);
holder.numberPicker.setMinValue(1);
holder.numberPicker.setMaxValue(10);
holder.numberPicker.setOnValueChangedListener(holder.listener);
holder.numberPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
#Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
currentCell=getItem(position);
View parentRow = (View) picker.getParent();
ListView mListView=(ListView)parentRow.getParent().getParent();
ConstraintLayout constraintLayoutView = (ConstraintLayout) mListView.getChildAt(currentCell.getPosition());
RelativeLayout relativeLayout = (RelativeLayout)constraintLayoutView.getChildAt(0);
NumberPicker p = (NumberPicker) relativeLayout.getChildAt(1);
if(position==currentCell.getPosition())
{
p.setValue(newVal);
}
else
{
p.setValue(oldVal);
}
}
});
//Set the name
TextView organName = (TextView)listItem.findViewById(R.id.organName);
organName.setText(QuickMeditationScreenInfo.getInstance().getScreenNameFromIndex(currentCell.getOrgan()));
return listItem;
}
Also even if i comment out the onValueChangeListener even then the same behaviour occurs which i assume is the default behaviour of number picker in a list. I have spent multiple hours on it but couldn't figure out the solution. I have also debugged the code and when i change a value, the debugger comes into the onValueChange code only once.
You need set numberpicker default value every time
holder = new ViewHolder();
holder.name = (TextView) listItem.findViewById(R.id.organName);
holder.numberPicker = (NumberPicker) ;
holder.numberPicker.setValue(defaultValue);//like this
Try to handle click event into adapter using interface like below
for example make one interface into adapter class ..
private onItemClick onItemClick;
public void setOnItemClick(DisplayAllData.onItemClick onItemClick) {
this.onItemClick = onItemClick;
}
public interface onItemClick{
void onItemSelected(int position); // pass your data
}
In getView() method like number listner called all logical code into activity or fragment.
holder.mTvName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onItemClick.onItemSelected(position);
}
});
In activity or fragment after adapter set into listview or recyclerview then
adapter not null then called below code..
allDataAdapter.setOnItemClick(new DisplayAllData.onItemClick() {
#Override
public void onItemSelected(int position) {
// here called all logical part
allDataAdapter.notifyDataSetChanged();
}
});
I have a fragment, ButtonSharingFragment, whose layout is called sharing_buttons.xml, it consists of 3 buttons.
I embed it in my NewContact activity with, in the layout of NewContact:
<fragment
android:name="com.example.chris.tutorialspoint.ButtonSharingFragment"
android:id = "#+id/myFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
My App loads up fine, I see the fragment where it is supposed to be. But I am trying to change the colour of one of the buttons in the fragment, when all checkboxes in my recyclerView are unchecked. The recyclerView is in my activity, NewContact. Can you tell me how to do this?
Here is my ButtonSharingFragment code:
public class ButtonSharingFragment extends Fragment{
Button phoneContacts;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
// Defines the xml file for the fragment
View buttonView = inflater.inflate(R.layout.sharing_buttons, parent, false);
//return inflater.inflate(R.layout.sharing_buttons, parent, false);
phoneContacts = (Button) buttonView.findViewById(R.id.btnPhoneContacts);
// Defines the xml file for the fragment
return buttonView;
}
}
And the OnBindViewHolder of my adapter, when a checkbox is clicked. What goes into if(count==0) { } ?
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, final int position) {
//The number of rows will match the number of phone contacts
final SelectPhoneContact selectPhoneContact = theContactsList.get(position);
//in the title textbox in the row, put the corresponding name etc...
((MatchingContact) viewHolder).title.setText(selectPhoneContact.getName());
((MatchingContact) viewHolder).phone.setText(selectPhoneContact.getPhone());
((MatchingContact) viewHolder).check.setChecked(theContactsList.get(position).getSelected());
((MatchingContact) viewHolder).check.setTag(position);
((MatchingContact) viewHolder).check.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//pos is the row number that the clicked checkbox exists in
Integer pos = (Integer) ((MatchingContact) viewHolder).check.getTag();
//NEED THIS TO PRESERVE CHECKBOX STATE
if (theContactsList.get(pos).getSelected()) {
theContactsList.get(pos).setSelected(false);
} else {
theContactsList.get(pos).setSelected(true);
}
//we want to keep track of checked boxes, so when it is '0'
//'Phone Contacts' button in ButtonSharingFragment will change
//HOW TO DO THIS?
int count;
count = 0;
int size = theContactsList.size();
for (int i = 0; i < size; i++) {
if (theContactsList.get(i).isSelected) {
count++;
}
}
Log.i("MyMessage","The count is " + count);
//if 'count' is 0, then change button colour in ButtonSharingFragment fragment
if (count==0){
//CHANGE COLOUR OF phoneContacts button in ButtonSharingFragment
//have tried interface/callback etc, must be doing it wrong
}
}
});
}
EDIT: Modified my code to look like below, but am getting NullPointerException.
I have created a java class called UpdateColorCallback :
public interface UpdateColorCallback {
void onUpdateColorCallback();
}
In my adapter I have included:
public class PopulistoContactsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder > {
private UpdateColorCallback updateColorCallback;
public void setUpdateLisenter(UpdateColorCallback updateColorCallback) {
this.updateColorCallback = updateColorCallback;
}
And in my ButtonSharingFragment:
public class ButtonSharingFragment extends Fragment implements UpdateColorCallback {
RecyclerView recyclerView;
Button publicContacts;
Button phoneContacts;
Button justMeContacts;
// ArrayList called selectPhoneContacts that will contain SelectPhoneContact info
ArrayList<SelectPhoneContact> selectPhoneContacts;
// The onCreateView method is called when Fragment should create its View object hierarchy,
// either dynamically or via XML layout inflation.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
PopulistoContactsAdapter adapter = new PopulistoContactsAdapter(selectPhoneContacts, getActivity());
adapter.setUpdateListener(this);
View buttonView = inflater.inflate(R.layout.sharing_buttons, parent, false);
//return inflater.inflate(R.layout.sharing_buttons, parent, false);
//for the Public, phoneContacts, justMe, save and cancel buttons
publicContacts = (Button) buttonView.findViewById(R.id.btnPublic);
phoneContacts = (Button) buttonView.findViewById(R.id.btnPhoneContacts);
justMeContacts = (Button) buttonView.findViewById(R.id.btnJustMe);
// Defines the xml file for the fragment
return buttonView;
}
#Override
public void onUpdateColorCallback() {
// TODO: Implement this
//Toast.makeText(getActivity(), "yes, this is working now"", Toast.LENGTH_SHORT).show();
Log.i("MyMessage","yes, this is working now");
}
}
Well, you need to make interface first then pass reference from fragment to adapter. Now when you want to change color or when you match your condition then you need to call.
Make Interface :-
public interface UpdateColorCallback {
void onUpdateColorCallback();
}
Now you need to implement into your fragment
public class ButtonSharingFragment extends Fragment implement UpdateColorCallback{
Button phoneContacts;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
// Defines the xml file for the fragment
View buttonView = inflater.inflate(R.layout.sharing_buttons, parent, false);
//return inflater.inflate(R.layout.sharing_buttons, parent, false);
// pass this from here to adapter
adapter.setUpdateLisenter(this);
phoneContacts = (Button) buttonView.findViewById(R.id.btnPhoneContacts);
// Defines the xml file for the fragment
return buttonView;
}
#Override
public void onUpdateColorCallback() {
//change button color
}
}
Adapter code:-
private UpdateColorCallback updateColorCallback;
public void setUpdateLisenter(UpdateColorCallback updateColorCallback) {
this.updateColorCallback = updateColorCallback;
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, final int position) {
// when ur condition meet then
if(updateColorCallback != null) {
// this call back call fragment
updateColorCallback. onUpdateColorCallback();
}
}
You can pass the Button instance to your adapter class from fragment and change the button state in the adapter,like:
adapter =new ButtonAdapter(button);
then in the adapter :
Button button1;
ButtonAdapter(Button button)
{
button1=button;
}
if (count==0){
button1.setBackgroundColor(getResources().getColor(R.color.white,null));
}
I need to update progress bar after i press the button inside my custom adapter.
Only when i declared view value as final i can do that. But it doesn't suit me.
What are the right solutions to do this ?
My custom adapter source:
public class DownloadListAdapter extends BaseAdapter implements DownloadManagerListener{
Context ctx;
LayoutInflater lInflater;
ArrayList<Product> objects;
View view;
DownloadListAdapter(Context context, ArrayList<Product> products) {
ctx = context;
objects = products;
lInflater = (LayoutInflater) ctx
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
view = convertView;
if (view == null) {
view = lInflater.inflate(R.layout.item, parent, false);
}
Product p = getProduct(position);
progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
progressBar.setProgress(p.size);
Button btSet = (Button) view.findViewById(R.id.btSet);
btSet.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//this does not work
progressBar.setProgress(100);
//this doesn't work too, it will work only when view will declared as final
ProgressBar pb = (ProgressBar) view.findViewById(R.id.progressBar);
pb.setProgress(100);
}
});
return view;
}
#Override
public void OnDownloadStarted(long taskId) {
//This method should also have access to view
}
#Override
public int getCount() {
return objects.size();
}
#Override
public Object getItem(int position) {
return objects.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
Product getProduct(int position) {
return ((Product) getItem(position));
}
}
As I understood when I read your code, you want to start download indicator (in this case, indicator is your progress bar). So you can try this way:
1. I assume that this is your DownloadManagerListener or you can change yours to this:
public interface DownloadManagerListener {
void OnDownloadStarted(long taskId, View view);
}
2. Change your button listener like this:
btSet.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ProgressBar progress = ((LinearLayout) v.getParent())
.findViewById(R.id.progressBar);
OnDownloadStarted(0, progress);
}
});
In this I assumed that your layout (R.layout.item) like that:
<LinelearLayout>
...
<ProgressBar android:id="#+id/progressBar"/>
...
<Button android:id="#+id/btSet"/>
</LinearLayout>
3. Finally your method OnDownloadStarted like this:
public void OnDownloadStarted(long taskId, View view) {
ProgressBar progressBar = (ProgressBar) view;
progressBar.setProgress(0);
}
UPDATE 1:
Base on author comment. I suggest following point:
1. Remove View view; from member off class and in getview method. Because when list view is populated, view reference to last item that has been call getView. So view member of adapter class is meaningless.
2. Change class which like this:
public class DownloadListAdapter extends BaseAdapter implements DownloadManagerListener{
Context ctx;
LayoutInflater lInflater;
ArrayList<Product> objects;
HashMap<Integer, ProgressBar> mProductDownloaderMap = new HashMap<Integer, ProgressBar>();
3. Chang getView() method like this:
if (convertView == null) {
convertView = lInflater.inflate(R.layout.item, parent, false);
}
Product p = getProduct(position);
progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
Button btSet = (Button) view.findViewById(R.id.btSet);
mProductDownloaderMap.put(position, progressBar);
btSet.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
OnDownloadStarted(position);// position is indicated taskID
}
});
4. On your dowload method:
public void OnDownloadStarted(long taskId) {
ProgressBar progressBar = mProductDownloaderMap.get(taskId);
progressBar.setProgress(0);
//Your download code here
}
Please let me know if I missunderstand your code/your purpose!
Also dont forget to mark this is anwsers if my answers is right for your question
Hope that help!
The view variable is global in the class so no need to make it final.
You should make the progressBar as final and change its progress inside button onClick method
I used fragment in my app and i'm using SQLite to save local data. But when I finished saving data, and I swipe the page, my listView is not refreshed with new data (Only showing old data). I have tried to provide a method notifyDataSetChanged() on my adapter, but it's not working.
My Base Adapter class :
public class LocalDataAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<LocalDataBean> data;
private static LayoutInflater inflater = null;
public LocalDataAdapter(Activity a, ArrayList<LocalDataBean> d) {
activity = a;
data = d;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int position) {
return data.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public void setItem(ArrayList<LocalDataBean> data){
this.data = data;
notifyDataSetChanged();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = inflater.inflate(R.layout.list_item, null);
TextView nama_konsumen = (TextView) v.findViewById(R.id.nama_konsumen);
TextView no_telp = (TextView) v.findViewById(R.id.no_telp);
TextView no_hp_cdma = (TextView) v.findViewById(R.id.no_hp_cdma);
TextView no_hp_gsm = (TextView) v.findViewById(R.id.no_hp_gsm);
LocalDataBean obj = (LocalDataBean) getItem(position);
nama_konsumen.setText(obj.getNamaKonsumen());
no_telp.setText(obj.getNoTelp());
no_hp_cdma.setText(obj.getNoCMDA());
no_hp_gsm.setText(obj.getNoGSM());
return v;
}
}
My fragment class :
public class LocalDataFragment extends Fragment {
View view;
Activity act;
SQLHandlerBean utilSql;
ArrayList<LocalDataBean> localdatabean = new ArrayList<LocalDataBean>();
LocalDataAdapter adapter;
ListView list;
public static final String TAG = LocalDataFragment.class.getSimpleName();
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.layout_local_data, null);
act = getActivity();
list = (ListView) view.findViewById(R.id.listViewLocalData);
utilSql = new SQLHandlerBean(this.act);
adapter = new LocalDataAdapter(act, localdatabean);
localdatabean = new ArrayList<LocalDataBean>();
list.setAdapter(adapter);
if (utilSql.ReadAllLocalData().size() < 1) {
Toast.makeText(act, "DATA EMPTY!", Toast.LENGTH_LONG).show();
} else {
localdatabean = utilSql.ReadAllLocalData();
Log.e(TAG, "TOTAL DATA : "+localdatabean.size());
adapter.setItem(localdatabean);
adapter.notifyDataSetChanged();
}
return view;
}
}
Is adapter.notifyDataSetChanged() placement correct?
No, the placement is not in the right place.
As you have placed the notifyDataSetChanged() inside of the onCreateView() method. It will be only invoked 1st time the fragment is launched.
Rather you can add a refresh button in your layout (or in you action bar). And along with the insertion/deletion method of the data, place the notifyDataSetChanged() at the bottom of the click event of that button.
By doing this user can refresh the page whenever they want.
And if you want to refresh the page by swipping the view then, SwipeRefreshLaoyout could be a perfect alternative.
You can check this blog.