I have a RecyclerView and a button for 'Binding' each item (Moving to another child at the DB).
Most of the time it works well, but sometimes i'm receiving indexOutOfBounds Exception.
This is a screen shot:
When I press at 'BIND' at the top recycler view item, i'm receiving this bug.
I made it print this line:
Log.d("dDebug","Almost bug! Size: " + ((MissionAdapter) MissionAdapter.this).mSnapshots.size() + " , index: " + missionPosition);
And it prints this:
D/dDebug: Almost bug! Size: 1 , index: 1
Here you can see the bug - size 1, index 1, so it will have indexOutOfBounds.
This is the code:
public class AvailableFragmentPilot extends Fragment {
private String TAG = "dDEBUG";
private RecyclerView mavailableList;
private DatabaseReference mAvailableMissionsDb, mPendingMissionsDb;
private FirebaseAuth mAuth;
private ProgressDialog mSubmitMsnProgress;
private String mCurrent_pilot_id;
private View mMainView;
// Query queries;
public AvailableFragmentPilot() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mMainView = inflater.inflate(R.layout.fragment_of_recycler_view_user, container, false);
mavailableList = (RecyclerView)mMainView.findViewById(R.id.mission_recycler_user);
mAuth = FirebaseAuth.getInstance();
mSubmitMsnProgress = new ProgressDialog(getContext());
mCurrent_pilot_id = mAuth.getCurrentUser().getUid();
mAvailableMissionsDb = FirebaseDatabase.getInstance().getReference().child("Missions").child("Available");
mAvailableMissionsDb.keepSynced(true);
mPendingMissionsDb = FirebaseDatabase.getInstance().getReference().child("Missions").child("Pending");
mPendingMissionsDb.keepSynced(true);
// queries = mAvailableMissionsDb.orderByChild("user_uid").equalTo(mCurrent_pilot_id);
mavailableList.setHasFixedSize(true);
mavailableList.setLayoutManager(new LinearLayoutManager(getContext()));
// Inflate the layout for this fragment
return mMainView;
}
#Override
public void onStart() {
super.onStart();
mavailableList.setAdapter(new MissionAdapter(mAvailableMissionsDb));
}
private class MissionAdapter extends FirebaseRecyclerAdapter<Mission, AvailableFragmentPilot.MissionsViewHolder> {
public MissionAdapter(Query queries){
super(Mission.class, R.layout.missions_single_layout, AvailableFragmentPilot.MissionsViewHolder.class, queries);
}
#Override
protected void populateViewHolder(AvailableFragmentPilot.MissionsViewHolder missionViewHolder, final Mission missionModel, final int missionPosition) {
Log.d(TAG, "inside populateViewHolder" + missionModel.getType() + " , " + missionModel.getDescription());
missionViewHolder.setMissionName(missionModel.getType());
missionViewHolder.setMissionDescription(missionModel.getDescription());
missionViewHolder.setMissionStatus(missionModel.getStatus());
missionViewHolder.button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Mission clickedMission = null;
if (((MissionAdapter) MissionAdapter.this).mSnapshots.size()>missionPosition){
clickedMission = AvailableFragmentPilot.MissionAdapter.this.getItem(missionPosition);
Log.d("dDebug","Ein bug. Size: " + ((MissionAdapter) MissionAdapter.this).mSnapshots.size() + " , index: " + missionPosition + " , mission: " + clickedMission.getType() + ": " + clickedMission.getDescription());
}
else{
Log.d("dDebug","Almost bug! Size: " + ((MissionAdapter) MissionAdapter.this).mSnapshots.size() + " , index: " + missionPosition);
}
if (clickedMission != null){ // for the sake of being extra-safe
// String url_str = getRef(missionPosition).toString();
// String uuid_for_mission = url_str.split("/")[5];
Log.d(TAG,"The button was pressed for mission: " + clickedMission.getType() + " , uid: " + missionModel.getMission_uid());
// removeMission(uuid_for_mission);
bindMission(clickedMission);
}
}
});
}
}
public void bindMission(final Mission mission){
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setCancelable(false);
builder.setTitle("Mission bind");
builder.setMessage("Are you sure you want to bind this mission?");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
mAvailableMissionsDb.child(mission.getMission_uid()).setValue(null);
final HashMap<String, String> missionMap = new HashMap<>();
missionMap.put("username", mission.getUsername());
missionMap.put("user_uid", mission.getUser_uid());
missionMap.put("mission_uid", mission.getMission_uid());
missionMap.put("type", mission.getType());
missionMap.put("status", "Pending");
missionMap.put("description", mission.getDescription());
missionMap.put("x", String.valueOf(mission.getX()));
missionMap.put("y", String.valueOf(mission.getY()));
missionMap.put("pilot_uid", mCurrent_pilot_id);
mPendingMissionsDb.child(mission.getMission_uid()).setValue(missionMap).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()){
// Log.d("dDebug","Before");
mSubmitMsnProgress.dismiss();
Toast.makeText(getContext(), ("Bind to mission " + mission.getType()),
Toast.LENGTH_LONG).show();
Log.d("dDebug","Painting in Red 1");
}
else {
Toast.makeText(getContext(), "Something went wrong",
Toast.LENGTH_SHORT).show();
}
}
});
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Log.d("dDebug","ok, not binding");
}
});
// Create the AlertDialog object and return it
builder.create().show();
}
public static class MissionsViewHolder extends RecyclerView.ViewHolder {
View mView;
Button button ;
public MissionsViewHolder(View itemView) {
super(itemView);
mView = itemView;
button = (Button)mView.findViewById(R.id.mission_single_button);
button.setText("BIND");
}
public void setMissionName(String name){
TextView mMissionNameView = mView.findViewById(R.id.mission_single_name);
mMissionNameView.setText(name);
}
public void setMissionStatus(String status){
TextView mMissionStatusView = mView.findViewById(R.id.mission_single_status);
mMissionStatusView.setText(status);
if (status.equals("Available")){
mMissionStatusView.setTextColor(Color.parseColor("#008000"));;
} else {
mMissionStatusView.setTextColor(Color.parseColor("#FF0000"));;
}
}
public void setMissionDescription(String description){
TextView mMissionDescriptionView = mView.findViewById(R.id.mission_single_description);
mMissionDescriptionView.setText(description);
}
}
}
In addition - sometimes I will have 5 items, I'll press at the most upper one, (Should be index 0!) - and the SECOND item is being moved (at index 1).
So it means that probarely something is wrong with the way i'm getting the item that was clciked.
Rookie recycler view mistake: the view holder can move around and be reused (thus changing its position) while the onClick callback will only store a reference to the original position. To fix that, use viewHolder.getAdapterPosition(). 👍
Related
I'm following Mesibo Tutorial for the First App and trying to integrate it in my app. The difference to the source code of tutorial https://github.com/mesibo/samples/tree/master/android/java/FirstApp is only that I have implemented it in Fragment instead of Activity and using databinding for views.
Every time if I'm clicking to LOGIN_AS_USER1 or LOGIN_AS_USER2 Button it shows connection Status 5. The created users are never online.
The users with corresponding user addresses and app ID (app Package) were created manually in Mesibo console. Tokens, addresses and app ID are double checked.
My Fragment code:
public class CommunicationFragment extends Fragment implements Mesibo.ConnectionListener, Mesibo.MessageListener {
private FragmentCommunicationBinding binding;
class DemoUser {
public String token;
public String name;
public String address;
DemoUser(String token, String name, String address) {
this.token = token;
this.name = name;
this.address = address;
}
}
//Refer to the Get-Started guide to create two users and their access tokens
DemoUser mUser1 = new DemoUser("631b138a5bfd2827b20d312721ee6549198539a5041517df2e33311958", "User-1", "1233");
DemoUser mUser2 = new DemoUser("ae80d38f59a814b3f4694055bbd90005c2fdae2ae7a530fe44311959", "User-2", "4566");
DemoUser mRemoteUser;
Mesibo.UserProfile mProfile;
Mesibo.ReadDbSession mReadSession;
Button mSendButton, mUiButton, mAudioCallButton, mVideoCallButton;
Button mLoginButton1, mLoginButton2;
TextView mMessageStatus, mConnStatus;
EditText mMessage;
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_communication, container, false);
View view = binding.getRoot();
mLoginButton1 = binding.login1;
mLoginButton2 = binding.login2;
mSendButton = binding.send;
mUiButton = binding.launchUI;
mAudioCallButton = binding.audioCall;
mVideoCallButton = binding.videoCall;
mMessageStatus = binding.msgStatus;
mConnStatus = binding.connStatus;
mMessage = binding.message;
mSendButton.setEnabled(false);
mUiButton.setEnabled(false);
mAudioCallButton.setEnabled(false);
mVideoCallButton.setEnabled(false);
mLoginButton1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mesiboInit(mUser1, mUser2); }
});
mLoginButton2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mesiboInit(mUser2, mUser1); }
});
mSendButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Mesibo.MessageParams p = new Mesibo.MessageParams();
p.peer = mRemoteUser.address;
p.flag = Mesibo.FLAG_READRECEIPT | Mesibo.FLAG_DELIVERYRECEIPT;
Mesibo.sendMessage(p, Mesibo.random(), mMessage.getText().toString().trim());
mMessage.setText("");}
});
mUiButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
MesiboUI.launchMessageView(getActivity(), mRemoteUser.address, 0);
}
});
mAudioCallButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
MesiboCall.getInstance().callUi(getActivity(), mProfile.address, false);
}
});
mVideoCallButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
MesiboCall.getInstance().callUi(getActivity(), mProfile.address, true);
}
});
return view;
}
private void mesiboInit(DemoUser user, DemoUser remoteUser) {
Mesibo api = Mesibo.getInstance();
api.init(getActivity().getApplicationContext());
Mesibo.addListener(this);
Mesibo.setSecureConnection(true);
Mesibo.setAccessToken(user.token);
Mesibo.setDatabase("mydb", 0);
Mesibo.start();
mRemoteUser = remoteUser;
mProfile = new Mesibo.UserProfile();
mProfile.address = remoteUser.address;
mProfile.name = remoteUser.name;
Mesibo.setUserProfile(mProfile, false);
// disable login buttons
mLoginButton1.setEnabled(false);
mLoginButton2.setEnabled(false);
// enable buttons
mSendButton.setEnabled(true);
mUiButton.setEnabled(true);
mAudioCallButton.setEnabled(true);
mVideoCallButton.setEnabled(true);
MesiboCall.getInstance().init(getActivity().getApplicationContext());
// Read receipts are enabled only when App is set to be in foreground
Mesibo.setAppInForeground(getActivity(), 0, true);
mReadSession = new Mesibo.ReadDbSession(mRemoteUser.address, this);
mReadSession.enableReadReceipt(true);
mReadSession.read(100);
}
#Override
public void Mesibo_onConnectionStatus(int status) {
mConnStatus.setText("Connection Status: " + status);
}
#Override
public boolean Mesibo_onMessage(Mesibo.MessageParams messageParams, byte[] data) {
try {
String message = new String(data, "UTF-8");
Toast toast = Toast.makeText(getActivity().getApplicationContext(),
message,
Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.show();
} catch (Exception e) {
}
return true;
}
#Override
public void Mesibo_onMessageStatus(Mesibo.MessageParams messageParams) {
mMessageStatus.setText("Message Status: " + messageParams.getStatus());
}
#Override
public void Mesibo_onActivity(Mesibo.MessageParams messageParams, int i) {
}
#Override
public void Mesibo_onLocation(Mesibo.MessageParams messageParams, Mesibo.Location location) {
}
#Override
public void Mesibo_onFile(Mesibo.MessageParams messageParams, Mesibo.FileInfo fileInfo) {
}
}
Most likely you are creating a token using the wrong App ID
https://mesibo.com/documentation/faq/other/#i-am-not-getting-connection-status-1-online
If you are not getting connection status 1, and getting 4 or 5, you
are not passing the correct appid while creating a token. The appid
passed to create a token must match the Android package name declared
in the AndroidManifest.xml or iOS bundle id declared in the Xcode
project (for example, com.mesibo.xxx ). If you are using Javascript
API or other platforms, ensure that you pass the same app id to the
setAppName API call.
here is my recyclerview adapter classs
public class WebsiteAdapter extends RecyclerView.Adapter<WebsiteAdapter.WebsiteHolder> {
private List<Website> websites = new ArrayList<>();
private WebsiteViewModel websiteViewModel;
WebsiteAdapter(WebsiteViewModel viewModel){
this.websiteViewModel = viewModel;
}
#NonNull
#Override
public WebsiteHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.website_item, parent, false);
return new WebsiteHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull final WebsiteHolder holder, final int position) {
final Website currentWebsite = websites.get(position);
final Boolean bookmarkStatus = currentWebsite.getFavourite();
final List<WebPage> webPages = websiteViewModel.getRepository().getAllWebPagesForWebsite(currentWebsite.getWebsite_id());
holder.textViewTitle.setText(currentWebsite.getWebsiteName());
if(currentWebsite.getDescription() != null){
holder.textViewDescription.setText(currentWebsite.getDescription());
holder.textViewDescription.setVisibility(View.VISIBLE);
}
if(webPages!=null && !webPages.isEmpty()) {
holder.secondaryAdapter.setWebPages(webPages);
holder.expandCollapse.setVisibility(View.VISIBLE);
}
if(bookmarkStatus){
holder.isBookmarked = true;
holder.bookmarkButton.setBackgroundResource(R.drawable.ic_bookmark_24px);
} else {
holder.isBookmarked = false;
holder.bookmarkButton.setBackgroundResource(R.drawable.ic_bookmark_border_24px);
}
holder.cardViewWebsite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String websiteUrl = currentWebsite.getWebsite_url();
System.out.println("Description = " + currentWebsite.getDescription() + ", boomarked : " + currentWebsite.getFavourite());
List<WebPage> webPages = websiteViewModel.getRepository().getAllWebPagesForWebsite(currentWebsite.getWebsite_id());
for(WebPage webPage : webPages){
System.out.println("Web pages: ");
System.out.println(webPage.toString() + ", ");
}
launchWebsite(v.getContext(), websiteUrl);
}
});
holder.bookmarkButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("Website bookmarked before click : " + bookmarkStatus + ", Description is : " + currentWebsite.getDescription());
currentWebsite.setFavourite(!bookmarkStatus);
System.out.println("Website bookmark clicked, status has been set to : " + currentWebsite.getFavourite());
websiteViewModel.getRepository().websiteDao.updateWebsite(currentWebsite);
notifyItemChanged(position);
}
});
}
private void launchWebsite(Context context, String URL) {
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
builder.setStartAnimations(context, R.anim.push_off_screen_left, R.anim.push_onto_screen_from_right);
builder.setExitAnimations(context, R.anim.push_onto_screen_from_left, R.anim.push_off_screen_right);
CustomTabsIntent customTabsIntent = builder.build();
customTabsIntent.launchUrl(context,Uri.parse(URL));
}
#Override
public int getItemCount() {
return websites.size();
}
public void setWebsites(List<Website> websites) {
this.websites = websites;
notifyDataSetChanged();
}
class WebsiteHolder extends RecyclerView.ViewHolder {
private TextView textViewTitle;
private TextView textViewDescription;
private CardView cardViewWebsite;
private boolean isBookmarked; // ALSO FAVOURITED
private boolean isExpanded = false;
private Button expandCollapse;
private Button bookmarkButton;
private SecondaryAdapter secondaryAdapter;
private RecyclerView childRecyclerView;
public WebsiteHolder(View itemView) {
super(itemView);
textViewTitle = itemView.findViewById(R.id.text_view_title);
textViewDescription = itemView.findViewById(R.id.text_view_description);
cardViewWebsite = itemView.findViewById(R.id.cardViewWebsite);
bookmarkButton = itemView.findViewById(R.id.bookmarkButton);
childRecyclerView = itemView.findViewById(R.id.childRecyclerview);
expandCollapse = itemView.findViewById(R.id.expandCollapse);
expandCollapse.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isExpanded) {
collapseView();
} else {
expandView();
}
}
});
childRecyclerView.setLayoutManager(new LinearLayoutManager(itemView.getContext(), LinearLayoutManager.HORIZONTAL, false));
LayoutAnimationController animation = AnimationUtils.loadLayoutAnimation(itemView.getContext(), R.anim.layout_animation_slide_in);
childRecyclerView.setLayoutAnimation(animation);
childRecyclerView.setHasFixedSize(true);
secondaryAdapter = new SecondaryAdapter();
childRecyclerView.setAdapter(secondaryAdapter);
}
private void collapseView() {
isExpanded = false;
childRecyclerView.setVisibility(View.GONE);
}
private void expandView() {
isExpanded = true;
childRecyclerView.setVisibility(View.VISIBLE);
}
}
}
The issue I am having is, when I press the bookmark button on item A: the expand button on a different item will appear when it should not. B: The secondaryRecyclerView gets set to some other website. How do I go about debugging this? Is there anything that jumps out as a culpit? I feel like I am setting somethings in the wrong place. Thanks very much
wrong item changes in recyclerview
Thanks to this post, I one, added in a bindView method, and 2: added ELSE statements to negate the if statements. Problems solved :) For now :)
I have succeeded in making more data download and then put it inside Recycleview and I succeeded in doing that and I used everything well but the problem is that I try to load some elements if they contain a value of 3, for example inside the function Loadmore I tried to make a loop and then I put the value 3 and then delete all the value equal to this number
but I have not succeeded so far please help and put the appropriate code
// my code
public class Page_6Fragment extends android.support.v4.app.Fragment implements AdapterView.OnItemSelectedListener {
TextView th, tm, tt, tapm;
Spinner spin_h, spin_m, spin_apm, spin_day;
RadioButton radioReject,radioAccipt ;
RadioGroup radioGroup;
Button buttonDialogReject,buttonDialogAccipt;
Dialog dialog;
RecyclerView recyclerView;
List<Customer> customers;
CustomerAdapter adapter;
View rootView;
String TAG = "MainActivity - ";
Context context;
API api;
Boolean acceptOrNo = true;
Context c = null;
String lock;
public int[] userLock;
public static Page_6Fragment instance;
public static Page_6Fragment newInstance() {
Page_6Fragment fragment = new Page_6Fragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.activity_customer, container, false);
this.context = getActivity();
this.instance = this;
recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
customers = new ArrayList<>();
// Postion is index item inside recycleview =
adapter = new CustomerAdapter(Page_6Fragment.this,customers){
#Override
public void buttonClickEvent(int position){
// Toast.makeText(context,"posIs: "+position+" userLock.len= "+userLock.length,Toast.LENGTH_SHORT).show();
//showDialog(context,customers.get(position).user_id , Integer.parseInt(customers.get(position).id));
//---- condithion 1
if(customers.get(position).status ==0){
showDialog(context,customers.get(position).user_id , Integer.parseInt(customers.get(position).id));
}else{
Toast.makeText(context,"تم الرد على هذا المستخدم مسبقا", Toast.LENGTH_SHORT).show();
}
}
};
adapter.setLoadMoreListener(new CustomerAdapter.OnLoadMoreListener() {
#Override
public void onLoadMore() {
recyclerView.post(new Runnable() {
#Override
public void run() {
int index = customers.size();
loadMore(index);
}
});
//Calling loadMore function in Runnable to fix the
// java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling error
}
});
recyclerView.setHasFixedSize(true);
// recyclerView.addItemDecoration(new VerticalLineDecorator(2));
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.setAdapter(adapter);
api = ServiceGenerator.createService(API.class);
load(0);
return rootView;
}
// load data first time
private void load(int index) {
Call<List<Customer>> call = api.getCustomer(index);
call.enqueue(new Callback<List<Customer>>() {
#Override
public void onResponse(Call<List<Customer>> call, final Response<List<Customer>> response) {
// Toast.makeText(MainActivity.this, "tost "+response.body().get(0).post_writer, Toast.LENGTH_LONG).show();
//Log.i("TRUE_TRUE_","Yes "+response.body().get(2).name);
if (response.isSuccessful()) {
//Log.i("TRUE_TRUE3","Yes"+response.body().toString());
//movies.addAll(response.body());
//adapter.notifyDataChanged();
getActivity().runOnUiThread(new Runnable(){
public void run() {
// No.1 ..............
// ShowDataScreen();
// Toast.makeText( MainActivity.this, "ShowDataScreen",Toast.LENGTH_SHORT).show();
//if(customers.get()){
customers.addAll(response.body());
adapter.notifyDataChanged();
initiUserlock(customers.size());
}
});// end of No.1 UI new thread
getActivity().runOnUiThread(new Runnable() {
public void run() {//No.2
// Toast.makeText( MainActivity.this, "This is correct way",Toast.LENGTH_SHORT).show();
}
});// end of No.2 UI new thread
// Toast.makeText(MainActivity.this, "tost "+response.body().get(0).post_writer, Toast.LENGTH_LONG).show();
} else {
Log.e(TAG, " Response Error " + String.valueOf(response.code()));
}
}
#Override
public void onFailure(Call<List<Customer>> call, Throwable t) {
Log.e(TAG, " Response Error " + t.getMessage());
}
});
}
// laod more data ...................................
private void loadMore(int index) {
// add loading progress view ....
//Toast.makeText(context, "loadMore", Toast.LENGTH_LONG).show();
customers.add(new Customer("load"));
// customers.get(index).user_id =2;
adapter.notifyItemInserted(customers.size() - 1);
Call<List<Customer>> call = api.getCustomer(index);
call.enqueue(new Callback<List<Customer>>() {
#Override
public void onResponse(Call<List<Customer>> call, Response<List<Customer>> response) {
if (response.isSuccessful()) {
//Toast.makeText(context, "it is Successful", Toast.LENGTH_LONG).show();
customers.remove(customers.size() - 1);
List<Customer> result = response.body();
// Log.i("Getresult{--: ", " "+result.get());
if(result.size()>0) {
customers.addAll(result);
//add loaded data
// How to delete every item = 3 from customers list
for (int i=0; i<customers.size(); i++) {
if(customers.get(i).user_id == 3){
// customers.remove(i);
}
}
} else {
//result size 0 means there is no more data available at server
adapter.setMoreDataAvailable(false);
//telling adapter to stop calling load more as no more server data available
Toast.makeText(context,"لايوجد بيانات اخرى", Toast.LENGTH_LONG).show();
}
adapter.notifyDataChanged();
//should call the custom method adapter.notifyDataChanged here to get the correct loading status
} else {
Log.e(TAG, " Load More Response Error000 " + String.valueOf(response.code()));
}
}
#Override
public void onFailure(Call<List<Customer>> call,Throwable t) {
Log.e(TAG, " Load More Response Error_11 " + t.getMessage());
}
});
}
As you already have the new list in the result list, you can solve it by using the result List and add it to the customers List
customers.clear();
for(Customer newCustomer: result){
if(newCustomer.user_id != 3){
customers.add(newCustomer);
}
}
Second option would be to iterate over the customers list using ListIterator
ListIterator<Customer> iter = customers.listIterator();
while(iter.hasNext()){
if(iter.next().user_id == 3){
iter.remove();
}
}
Or
customers.removeIf(customer -> customer.user_id == 3);
I have the following problem.
Activity 1: Where do I send a user ID by PutExtra.
Activity 2: Get the data with GetExtra.
At some point in Activity 2 I send to Activity 3, sending is done again with PutExtra.
I want to go back to activity 2, sending the data as PutExtra. But in activity 2 you already have a GetExtra that expects the data from activity 1, so it is giving an error. How can I send this data from Activity 3 to Activity 2 and not conflict with Activity 2 because I already expect data with GetExtra from Activity 1.
Note: The data sent is always the same. It is always the user ID that is sent as PutExtra and also received as GetExtra.
EDIT:
Code sending or given from Activity 2 to Activity 3
public class PerfilEmpTab2 extends Fragment {
private RecyclerView mCardServicoList;
private String mId_Empresa = null;
private DatabaseReference mDatabaseServicos;
private boolean mProcessAddServico = false;
public PerfilEmpTab2() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_perfil_emp_tab2, container, false);
/* Recebe id de outra tela*/
mId_Empresa = getActivity().getIntent().getExtras().getString("id_empresa");
mDatabaseServicos = FirebaseDatabase.getInstance().getReference().child("Produtos_Empresas").child(mId_Empresa);
/*Recuperar REcyclerView*/
mCardServicoList = (RecyclerView) view.findViewById(R.id.cardListaServicos);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
linearLayoutManager.setReverseLayout(true);
linearLayoutManager.setStackFromEnd(true);
//mCardCategList.setHasFixedSize(true);
mCardServicoList.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
/*Fim Recycler View*/
loadServicos();
return view;
}
private void loadServicos() {
FirebaseRecyclerAdapter<CardServico_row, CardServicosViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<CardServico_row, CardServicosViewHolder>(
CardServico_row.class,
R.layout.card_servicos_row,
CardServicosViewHolder.class,
mDatabaseServicos
) {
#Override
protected void populateViewHolder(final CardServicosViewHolder viewHolder, final CardServico_row model, int position) {
final String servico_key = getRef(position).getKey();
final String nome_produto = model.getNome_produto();
final String duracao = model.getDuracao();
final String valor = model.getValor();
final String valorOld = model.getValorOld();
viewHolder.setNome_produto(model.getNome_produto());
viewHolder.setDuracao(model.getDuracao());
viewHolder.setValor(model.getValor());
viewHolder.setValorOld(model.getValorOld());
/*Clique na view*/
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intentServicoDetalhes = new Intent(getActivity(), ServicoDetalhes.class);
intentServicoDetalhes.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentServicoDetalhes.putExtra("id_empresa", mId_Empresa);
startActivity(intentServicoDetalhes);
}
});
viewHolder.mAddBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Toast.makeText(Categorias.this, nome + post_key, Toast.LENGTH_LONG).show();
CharSequence opcoes[] = new CharSequence[] {"Editar Serviço", "Ver Detalhes"};
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
//builder.setTitle("Opçoes");
//builder.setCancelable(false);
builder.setItems(opcoes, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// the user clicked on colors[which]
switch (which) {
case 0:
Toast.makeText(getActivity().getApplication(), "Dados" + "-" + servico_key + "-" + nome_produto + "-" + duracao + "-" + valor + "-" + valorOld, Toast.LENGTH_LONG).show();
/*Intent criarSubC = new Intent(Categorias.this, CadastroSubCategorias.class);
criarSubC.putExtra("id_categ", post_key);
startActivity(criarSubC);*/
mProcessAddServico = false;
break;
case 1:
Toast.makeText(getActivity().getApplication(), "Dados" + "-" + servico_key + "-" + nome_produto + "-" + duracao + "-" + valor + "-" + valorOld, Toast.LENGTH_LONG).show();
mProcessAddServico = false;
break;
}
}
});
builder.show();
}
});
}
};
mCardServicoList.setAdapter(firebaseRecyclerAdapter);
}
public static class CardServicosViewHolder extends RecyclerView.ViewHolder{
View mView;
ImageButton mAddBtn;
public CardServicosViewHolder (View itemView){
super(itemView);
mView = itemView;
mAddBtn = (ImageButton) mView.findViewById(R.id.addServico_tab2);
}
public void setNome_produto(String nome_produto){
TextView card_nomeProduto = (TextView) mView.findViewById(R.id.tvNomeProduto);
card_nomeProduto.setText(nome_produto);
}
public void setDuracao(String duracao){
TextView card_duracao = (TextView) mView.findViewById(R.id.tvDuracao);
card_duracao.setText(duracao);
}
public void setValor(String valor){
TextView card_valor = (TextView) mView.findViewById(R.id.tvValor);
card_valor.setText(valor);
}
public void setValorOld(final String valorOld){
if ( valorOld != null ){
TextView card_valorOld = (TextView) mView.findViewById(R.id.tvValorOld);
card_valorOld.setText(valorOld);
card_valorOld.setPaintFlags(card_valorOld.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); // Risca o texto
//card_valorOld.setPaintFlags(card_valorOld.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG)); // Remove o Risca o texto
} else {
TextView card_valorOld = (TextView) mView.findViewById(R.id.tvValorOld);
card_valorOld.setText(valorOld);
card_valorOld.setVisibility(View.GONE);
}
}
}
}
In Activity 3 I get:
mId_Empresa = getIntent().getExtras().getString("id_empresa");
When you start activity 3 call startActivityForResult(intent, code) instead of startActivity(intint). Then in Activity 3 override finish() and call setResult(Activity.RESULT_OK, data) where data is an object that you have created new Intent() and called putExtra data.putExtra(key, value) on as you want. Then in Activity 2 override onActivityResult(int requestCode, int resultCode, Intent data) to handle it. requestCode is the code you started the activity with. Be aware that onActivityResult occurs before onResume so attempting to update the UI from onActivityResult might not work as expected eg notifying an adapter.
Refer to this doc for more info
https://developer.android.com/training/basics/intents/result.html
EDIT: added code example
Starting activity 3 from activity 2:
static final int SERVICO_DETALHES_REQUEST = 1; // The request code
#Override
public void onClick(View view) {
{
Intent intentServicoDetalhes = new Intent(getActivity(), ServicoDetalhes.class);
intentServicoDetalhes.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentServicoDetalhes.putExtra("id_empresa", mId_Empresa);
startActivityForResult(intentServicoDetalhes, SERVICO_DETALHES_REQUEST );
}
Setting the result from activity 3:
#Override
public void finish()
{
Intent data = new Intent();
data.putExtra("id_empresa", "new_id");
setResult(Activity.RESULT_OK, data);
super.finish();
}
Handling the result from activity 2:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == SERVICO_DETALHES_REQUEST && resultCode == RESULT_OK)
String newId = data.getStringExtra("id_empresa");
}
I wanted to add swipe to refresh for my listview in a Fragment but it doesn't seem to work as it doesn't update my list view at all. Here is how my activity works:
Users open up PictureFragment where a list of images (listview)
are shown.
Users press "add button" which will open up UploadImageActivity to add in image.
Once done, UploadImageActivity will close and users now get back to PictureFragment (not updated their latest image upload yet).
User swipes down to update, << Doesn't update the latest image into listview!
Hope a kind soul can help me resolve this.
public class PictureFragment extends Fragment {
private ListView listView;
private int smiley_id;
private String title, date, caption, image;
private ImageButton addPicButton;
private SwipeRefreshLayout swipeRefreshLayout;
private PictureAdapter adapter;
private TableDatabase tableDatabase;
private Cursor cursor;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_picture, container, false);
// Set listview
listView = (ListView) rootView.findViewById(R.id.piclistView);
adapter = new PictureAdapter(getActivity().getApplicationContext(), R.layout.row_feed);
listView.setAdapter(adapter);
// Retrieve data from database
tableDatabase = new TableDatabase(getActivity());
// Get rows of database
cursor = tableDatabase.getInformation(tableDatabase);
// Start from the last so that listview displays latest image first
// Check for existing rows
if(cursor.moveToLast()) {
do {
// Get items from each column
smiley_id = cursor.getInt(0);
title = cursor.getString(1);
date = cursor.getString(2);
caption = cursor.getString(3);
image = cursor.getString(4);
// Saves images added by user into listview
PictureItem pictureItem = new PictureItem(smiley_id, title, date, caption, image);
adapter.add(pictureItem);
} while (cursor.moveToPrevious());
}
// Swipe on refresh
swipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipe_refresh);
swipeRefreshLayout.setEnabled(false);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
swipeRefreshLayout.setRefreshing(true);
(new Handler()).postDelayed(new Runnable() {
#Override
public void run() {
adapter.notifyDataSetChanged();
swipeRefreshLayout.setRefreshing(false);
}
}, 1000);
}
});
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if(firstVisibleItem == 0) swipeRefreshLayout.setEnabled(true);
else swipeRefreshLayout.setEnabled(false);
}
});
// Lead user to UploadImageActivity to insert image to listview
addPicButton = (ImageButton) rootView.findViewById(R.id.addPictureButton);
addPicButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(getActivity().getApplicationContext(), UploadImageActivity.class));
}
});
return rootView;
}
UploadImageActivity.java
public class UploadImageActivity extends ActionBarActivity implements View.OnClickListener{
private Calendar cal = Calendar.getInstance();
private SimpleDateFormat dateFormatter = new SimpleDateFormat("dd MMM yyyy, EEE # hh:mm a");
EditText pic_title, pic_caption;
ImageView picture;
Button smiley1, smiley2, smiley3, smiley4, smiley5, selected_smiley;
// To store in database
int smiley_id = R.drawable.smile1; // Set default smiley as first smiley if not chosen
String title, date, caption;
String uriPicture; // Save uri in string format to store image as text format in database
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_picture);
// Removes shadow under action bar
getSupportActionBar().setElevation(0);
pic_title = (EditText) findViewById(R.id.picture_title);
pic_caption = (EditText) findViewById(R.id.picture_caption);
picture = (ImageView) findViewById(R.id.imagebutton);
smiley1 = (Button) findViewById(R.id.button1);
smiley2 = (Button) findViewById(R.id.button2);
smiley3 = (Button) findViewById(R.id.button3);
smiley4 = (Button) findViewById(R.id.button4);
smiley5 = (Button) findViewById(R.id.button5);
selected_smiley = (Button) findViewById(R.id.select_smiley);
picture.setOnClickListener(this);
smiley1.setOnClickListener(this);
smiley2.setOnClickListener(this);
smiley3.setOnClickListener(this);
smiley4.setOnClickListener(this);
smiley5.setOnClickListener(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_event, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_ok) {
title = pic_title.getText().toString();
date = dateFormatter.format(cal.getTime());
caption = pic_caption.getText().toString();
// Do not save data
if(title.isEmpty()) {
alertUser("Upload failed!", "Please enter title.");
}
else if(caption.isEmpty()) {
alertUser("Upload failed!", "Please enter caption.");
}
else if(uriPicture.isEmpty()) {
alertUser("Upload failed!", "Please upload an image.");
}
// Save data when title, caption and image are not empty
else {
// Add information into database
TableDatabase tableDatabase = new TableDatabase(this);
tableDatabase.putInformation(tableDatabase, smiley_id, title, date, caption, uriPicture);
Toast.makeText(getBaseContext(), "Details successfully saved", Toast.LENGTH_LONG).show();
finish();
}
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onClick(View v) {
switch(v.getId()) {
// Show the image picked by user
case R.id.imagebutton:
picture.setImageDrawable(null);
Crop.pickImage(this);
break;
// Saves the user's smiley choice
case R.id.button1:
selected_smiley.setBackgroundResource(R.drawable.smile1);
selected_smiley.setText("");
setSmileyID(R.drawable.smile1);
break;
case R.id.button2:
selected_smiley.setBackgroundResource(R.drawable.smile2);
selected_smiley.setText("");
setSmileyID(R.drawable.smile2);
break;
case R.id.button3:
selected_smiley.setBackgroundResource(R.drawable.smile3);
selected_smiley.setText("");
setSmileyID(R.drawable.smile3);
break;
case R.id.button4:
selected_smiley.setBackgroundResource(R.drawable.smile4);
selected_smiley.setText("");
setSmileyID(R.drawable.smile4);
break;
case R.id.button5:
selected_smiley.setBackgroundResource(R.drawable.smile5);
selected_smiley.setText("");
setSmileyID(R.drawable.smile5);
break;
default:
break;
}
}
// This method sets the smiley ID according to what the user picks.
private void setSmileyID(int smileyID) {
this.smiley_id = smileyID;
}
// This method calls alert dialog to inform users a message.
private void alertUser(String title, String message) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(UploadImageActivity.this);
dialogBuilder.setTitle(title);
dialogBuilder.setMessage(message);
dialogBuilder.setPositiveButton("Ok", null);
dialogBuilder.show();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == Crop.REQUEST_PICK && resultCode == RESULT_OK) {
beginCrop(data.getData());
} else if(requestCode == Crop.REQUEST_CROP) {
handleCrop(resultCode, data);
}
}
// This method allows users to crop image in square.
private void beginCrop(Uri source) {
Uri destination = Uri.fromFile(new File(getCacheDir(), "cropped"));
Crop.of(source, destination).asSquare().start(this);
}
// This method ensures there are no errors in cropping.
private void handleCrop(int resultCode, Intent result) {
if(resultCode == RESULT_OK) {
picture.setImageURI(Crop.getOutput(result));
uriPicture = Crop.getOutput(result).toString();
} else if(resultCode == Crop.RESULT_ERROR) {
Toast.makeText(this, Crop.getError(result).getMessage(), Toast.LENGTH_SHORT).show();
}
}
TableDatabase.java
public class TableDatabase extends SQLiteOpenHelper {
public String query = "CREATE TABLE " + TableData.TableInfo.TABLE_NAME + " (" +
TableData.TableInfo.SMILEY + " INTEGER NOT NULL, " +
TableData.TableInfo.TITLE + " TEXT, " +
TableData.TableInfo.DATE + " TEXT, " +
TableData.TableInfo.CAPTION + " TEXT, " +
TableData.TableInfo.IMAGE + " TEXT);";
public TableDatabase(Context context) {
super(context, TableData.TableInfo.DATABASE_NAME, null, TableData.TableInfo.DATABASE_VERSION);
// Check if database is created
Log.d("Database operations", "Database created");
}
#Override
public void onCreate(SQLiteDatabase db) {
// Create table
db.execSQL(query);
Log.d("Database operations", "Table created");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
// Insert user information into the database
public void putInformation(TableDatabase data, int smiley, String title, String date, String caption, String image) {
// Write data into database
SQLiteDatabase sqLiteDatabase = data.getWritableDatabase();
ContentValues contentValues = new ContentValues();
// Add value from each column into contentvalue
contentValues.put(TableData.TableInfo.SMILEY, smiley);
contentValues.put(TableData.TableInfo.TITLE, title);
contentValues.put(TableData.TableInfo.DATE, date);
contentValues.put(TableData.TableInfo.CAPTION, caption);
contentValues.put(TableData.TableInfo.IMAGE, image);
// Insert into sqlite database
sqLiteDatabase.insert(TableData.TableInfo.TABLE_NAME, null, contentValues);
Log.d("Database operations", "One row inserted");
}
// Retrieve data from database
public Cursor getInformation(TableDatabase data) {
// Read data from sqlite database
SQLiteDatabase sqLiteDatabase = data.getReadableDatabase();
String[] columns = { TableData.TableInfo.SMILEY, TableData.TableInfo.TITLE, TableData.TableInfo.DATE, TableData.TableInfo.CAPTION, TableData.TableInfo.IMAGE };
// Points to first row of table
return sqLiteDatabase.query(TableData.TableInfo.TABLE_NAME, columns, null, null, null, null, null);
}