Trying to retrieve data and place it into RecyclerView. But i always end up getting a null adapter error. My List Adapter is not being recognized.
I have initialized adapter and recyclerview in OnCreate(), OnViewCreated() nothing changed except app-crash.
Can you guys shed any light please?
My List Adapter:
public class PostListAdapter extends RecyclerView.Adapter<PostListAdapter.ViewHolder>{
private static final String TAG = "PostListAdapter";
private static final int NUM_GRID_COLUMNS = 3;
private ArrayList<Post> mPosts;
private Context mContext;
public class ViewHolder extends RecyclerView.ViewHolder{
SquareImageView mPostImage;
public ViewHolder(View itemView) {
super(itemView);
mPostImage = (SquareImageView) itemView.findViewById(R.id.post_image);
int gridWidth = mContext.getResources().getDisplayMetrics().widthPixels;
int imageWidth = gridWidth/NUM_GRID_COLUMNS;
mPostImage.setMaxHeight(imageWidth);
mPostImage.setMaxWidth(imageWidth);
}
}
ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(mContext);
public PostListAdapter(Context context, ArrayList<Post> posts) {
mPosts = posts;
mContext = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.layout_view_post, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
ImageLoader.getInstance().init(ImageLoaderConfiguration.createDefault(mContext));
UniversalImageLoader.setImage(mPosts.get(position).getImage(), holder.mPostImage);
//GlideApp.with(mContext).load(mPosts.get(position)).into(holder.mPostImage);
//imageLoader.displayImage(mPosts.get(position).getImage(), holder.mPostImage);
final int pos = position;
holder.mPostImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "onClick: selected a post");
//TODO
//view the post in more detail
}
});
}
#Override
public int getItemCount() {
return mPosts.size();
}
}
My Fragment (where i initiliaze adapter and recyclerview):
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_search, container, false);
mFilters = view.findViewById(R.id.ic_search);
mSearchText = view.findViewById(R.id.input_search);
mRecyclerView = view.findViewById(R.id.recyclerView);
mFrameLayout = view.findViewById(R.id.container);
getElasticSearchPassword();
init();
return view;
}
private void setupPostsList(){
RecyclerViewMargin itemDecorator = new RecyclerViewMargin(GRID_ITEM_MARGIN, NUM_GRID_COLUMNS);
mRecyclerView.addItemDecoration(itemDecorator);
GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), NUM_GRID_COLUMNS);
mRecyclerView.setLayoutManager(gridLayoutManager);
mAdapter = new PostListAdapter(getActivity(), mPosts);
mRecyclerView.setAdapter(mAdapter);
}
private void init(){
mFilters.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "onClick: navigating to filters activity.");
Intent intent = new Intent(getActivity(), FiltersActivity.class);
startActivity(intent);
}
});
mSearchText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if(actionId == EditorInfo.IME_ACTION_SEARCH
||actionId == EditorInfo.IME_ACTION_DONE
|| event.getAction() == KeyEvent.ACTION_DOWN
|| event.getKeyCode() == KeyEvent.KEYCODE_ENTER){
mPosts = new ArrayList<Post>();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
ElasticSearchAPI searchAPI = retrofit.create(ElasticSearchAPI.class);
HashMap<String, String> headerMap = new HashMap<String, String>();
headerMap.put("Authorization", Credentials.basic("", mElasticSearchPassword));
String searchString = "";
if(!mSearchText.equals("")){
searchString = searchString + mSearchText.getText().toString() + "*";
}
if(!mPrefCity.equals("")){
searchString = searchString + " city:" + mPrefCity;
}
if(!mPrefStateProv.equals("")){
searchString = searchString + " state_province:" + mPrefStateProv;
}
if(!mPrefCountry.equals("")){
searchString = searchString + " country:" + mPrefCountry;
}
Call<HitsObject> call = searchAPI.search(headerMap, "AND", searchString);
call.enqueue(new Callback<HitsObject>() {
#Override
public void onResponse(Call<HitsObject> call, Response<HitsObject> response) {
HitsList hitsList = new HitsList();
String jsonResponse = "";
try{
Log.d(TAG, "onResponse: server response: " + response.toString());
if(response.isSuccessful()){
hitsList = response.body().getHits();
}else{
jsonResponse = response.errorBody().string();
}
Log.d(TAG, "onResponse: hits: " + hitsList);
for(int i = 0; i < hitsList.getPostIndex().size(); i++){
Log.d(TAG, "onResponse: data: " + hitsList.getPostIndex().get(i).getPost().toString());
mPosts.add(hitsList.getPostIndex().get(i).getPost());
}
Log.d(TAG, "onResponse: size: " + mPosts.size());
//setup the list of posts
setupPostsList();
}catch (NullPointerException e){
Log.e(TAG, "onResponse: NullPointerException: " + e.getMessage() );
}
catch (IndexOutOfBoundsException e){
Log.e(TAG, "onResponse: IndexOutOfBoundsException: " + e.getMessage() );
}
catch (IOException e){
Log.e(TAG, "onResponse: IOException: " + e.getMessage() );
}
}
#Override
public void onFailure(Call<HitsObject> call, Throwable t) {
Log.e(TAG, "onFailure: " + t.getMessage() );
Toast.makeText(getActivity(), "search failed", Toast.LENGTH_SHORT).show();
}
});
}
return false;
}
});
}
public void viewPost(String postId){
ViewPostFragment fragment = new ViewPostFragment();
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
Bundle args = new Bundle();
args.putString(getString(R.string.arg_post_id), postId);
fragment.setArguments(args);
transaction.replace(R.id.container, fragment, getString(R.string.fragment_view_post));
transaction.addToBackStack(getString(R.string.fragment_view_post));
transaction.commit();
mFrameLayout.setVisibility(View.VISIBLE);
ImageLoader.getInstance().init(ImageLoaderConfiguration.createDefault(getActivity()));
}
#Override
public void onResume() {
super.onResume();
getFilters();
}
private void getElasticSearchPassword(){
Log.d(TAG, "getElasticSearchPassword: retrieving elasticsearch password.");
Query query = FirebaseDatabase.getInstance().getReference()
.child(getString(R.string.node_elasticsearch))
.orderByValue();
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
DataSnapshot singleSnapshot = dataSnapshot.getChildren().iterator().next();
mElasticSearchPassword = singleSnapshot.getValue().toString();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void getFilters(){
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
mPrefCity = preferences.getString(getString(R.string.preferences_city), "");
mPrefStateProv = preferences.getString(getString(R.string.preferences_state_province), "");
mPrefCountry = preferences.getString(getString(R.string.preferences_country), "");
Log.d(TAG, "getFilters: got filters: \ncity: " + mPrefCity + "\nState/Prov: " + mPrefStateProv
+ "\nCountry: " + mPrefCountry);
}
}
It seems like you never call the method setupPostsList(). You should move your code in Fragment from onCreateView() to onViewCreated() - that's the mehod where all views in fragment are created and you can use findViewById(). First find all view by ids and then call method setupPostsList() to set up the recycle view.
Related
I am trying to display posts from a server in listView. So I used recycle-view to achieve that. Everything is working fine except that ll items are displaying twice.
I counted the total fetched items from server, and the count is 5, but adapter.getItemCount is showing 10.
After searching hours on the internet, I tried following :
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
and
homeFragmentAdapter.setHasStableIds(true);
Below is my fragment...
package com.example.projectName;
import static android.content.Context.MODE_PRIVATE;
import static android.webkit.ConsoleMessage.MessageLevel.LOG;
import static com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions.withCrossFade;
public class HomeFollowersFragment extends Fragment implements InfiniteScrollListener.OnLoadMoreListener, RecyclerViewItemListener {
private static final String TAG = "HomeFollowersFragment";
private static final String URL = "https://api.androidhive.info/json/movies_2017.json";
private RecyclerView recyclerView;
private ProgressBar postLoader;
FFmpeg ffmpeg;
// private List<Movie> movieList;
// private HomeAdapter mAdapter;
private List<PostList> postListGlobal = new ArrayList<>();
List<VerticalDataModal> verticalDataModals;
List<HorizontalDataModal> horizontalDataModals;
private SwipeRefreshLayout swipeMore;
private InfiniteScrollListener infiniteScrollListener;
private HomeFragmentAdapter homeFragmentAdapter;
SharedPreferences sharedPreferences;
private Boolean isLoggedIn = false;
private String email = "";
private String token = "";
private String userId = "";
private Dialog customLoader;
SkeletonScreen skeletonScreen;
private int pastVisiblesItems, visibleItemCount, totalItemCount;
private boolean loading = false;
private EndlessScrollListener scrollListener;
SharedPreferences sp;
SharedPreferences.Editor Ed;
public HomeFollowersFragment() {
//super();
}
/**
* #return A new instance of fragment HomeFollowersFragment.
*/
public static HomeFollowersFragment newInstance() {
return new HomeFollowersFragment();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_home, container, false);
// ((AppCompatActivity) getActivity()).getSupportActionBar().show();
try{
sharedPreferences = getActivity().getSharedPreferences("Login", MODE_PRIVATE);
email = sharedPreferences.getString("email", null);
token = sharedPreferences.getString("token", null);
isLoggedIn = sharedPreferences.getBoolean("isLoggedIn", false);
userId = sharedPreferences.getString("id", null);
}catch (Exception e){
e.printStackTrace();
Log.d("StackError", "StackError: "+e);
}
sp = getActivity().getSharedPreferences("Posts", MODE_PRIVATE);
if(!isLoggedIn || token == null || userId == null){
Intent intent = new Intent(getActivity(), RegisterActivity.class);
intent.putExtra("loginFrom", "profile");
startActivity(intent);
}
recyclerView = view.findViewById(R.id.recycler_view);
postLoader = view.findViewById(R.id.post_loader);
swipeMore = view.findViewById(R.id.swipe_layout);
homeFragmentAdapter = new HomeFragmentAdapter(postListGlobal, this, "home");
if(sp.contains("postListGlobal"))
skeletonScreen = Skeleton.bind(recyclerView)
.adapter(homeFragmentAdapter)
.shimmer(true)
.angle(20)
.frozen(false)
.duration(1200)
.count(10)
.load(R.layout.item_skelton_home_page)
.show(); //default count is 10
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 2);
StaggeredGridLayoutManager sLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(sLayoutManager);
homeFragmentAdapter.setHasStableIds(true);
recyclerView.setAdapter(homeFragmentAdapter);
recyclerView.setNestedScrollingEnabled(false);
customLoader = new Dialog(getActivity(), R.style.crystal_range_seek_bar);
customLoader.setCancelable(false);
View loaderView = getLayoutInflater().inflate(R.layout.custom_loading_layout, null);
customLoader.getWindow().getAttributes().windowAnimations = R.style.crystal_range_seek_bar;
customLoader.getWindow().setBackgroundDrawableResource(R.color.translucent_black);
ImageView imageLoader = loaderView.findViewById(R.id.logo_loader);
Glide.with(this).load(R.drawable.logo_loader).into(imageLoader);
customLoader.setContentView(loaderView);
if(homeFragmentAdapter.getItemCount() == 0 && !loading){
// server fetchdata
Log.d(TAG, "no item available..");
postLoader.setVisibility(View.VISIBLE);
loading = true;
fetchStoreItems();
}else{
postLoader.setVisibility(View.GONE);
}
swipeMore.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
Log.d(TAG, "on refresh...");
fetchStoreItems();
}
});
return view;
}
#Override
public void onItemClicked(int position) {
Log.d(TAG, "click position: "+position);
Toast.makeText(getActivity(),postListGlobal.get(position).getTitle(),Toast.LENGTH_SHORT).show();
// Toast.makeText(getActivity(),""+position, Toast.LENGTH_SHORT).show();
}
public int getLastVisibleItem(int[] lastVisibleItemPositions) {
int maxSize = 0;
for (int i = 0; i < lastVisibleItemPositions.length; i++) {
if (i == 0) {
maxSize = lastVisibleItemPositions[i];
}
else if (lastVisibleItemPositions[i] > maxSize) {
maxSize = lastVisibleItemPositions[i];
}
}
return maxSize;
}
#Override
public void onLoadMore() {
homeFragmentAdapter.addNullData();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
homeFragmentAdapter.removeNull();
Toast.makeText(getContext(), "load more here...", Toast.LENGTH_LONG).show();
// fetchStoreItems();
swipeMore.setRefreshing(false);
}
}, 2000);
}
private void fetchStoreItems() {
RequestQueue queue = Volley.newRequestQueue(getActivity());
Log.d(TAG, "Post Data Followers: "+Constant.FETCH_POSTS_API);
CacheRequest cacheRequest = new CacheRequest(0, Constant.FETCH_POSTS_API, new Response.Listener<NetworkResponse>() {
#Override
public void onResponse(NetworkResponse response) {
try {
final String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
if (response == null) {
Toast.makeText(getActivity(), "Couldn't fetch the store items! Pleas try again.", Toast.LENGTH_LONG).show();
loading = false;
return;
}
JSONObject postObj = new JSONObject(jsonString);
System.out.println("post full data... : " + postObj);
if (postObj.getBoolean("Status")) {
try {
postLoader.setVisibility(View.GONE);
JSONArray arrayResponse = postObj.optJSONArray("Data");
int dataArrLength = arrayResponse.length();
if(dataArrLength == 0){
Toast.makeText(getActivity(), "No posts available at this time, you can create yout own post by clicking on mic button", Toast.LENGTH_SHORT).show();
}
postListGlobal.clear();
Log.d(TAG, "Total Posts count: "+dataArrLength);
for(int i=0; i<dataArrLength; i++) {
try {
JSONObject dataListObj = arrayResponse.optJSONObject(i);
System.out.println("post full data... : " + dataListObj);
JSONObject postDetailObj = dataListObj.optJSONObject("post_detail");
JSONObject followDtatusObj = dataListObj.optJSONObject("follow_status");
JSONArray postFilesArr = dataListObj.optJSONArray("post_files");
JSONObject userDatasObj = postDetailObj.optJSONObject("user");
String userId = userDatasObj.optString("id");
String userName = userDatasObj.optString("email");
String userImage = userDatasObj.optString("email");
boolean followStatus = followDtatusObj.optBoolean("follow");
String postId = postDetailObj.optString("id");
String postTitle = postDetailObj.optString("post_title");
String postDescription = postDetailObj.optString("post_description");
String postCoverUrl = postDetailObj.optString("post_coverurl", "1");
String postViewType = postDetailObj.optString("view_type", "1");
String postAllowComment = postDetailObj.optString("allow_comments", "1");
String postAllowDownload = postDetailObj.optString("allow_download", "1");
String postTotalPost = postDetailObj.optString("total_post", "1");
String postPostSection = postDetailObj.optString("post_section", "image");
String postActiveStatus = postDetailObj.optString("is_active", "1");
String postTotalViews = postDetailObj.optString("total_watched","0");
String postTotalShare = postDetailObj.optString("total_share","0");
String postTotalDownload = postDetailObj.optString("total_download","0");
String postTotalReaction = postDetailObj.optString("total_reaction","0");
String postTotalLike = postDetailObj.optString("total_like","0");
String postTotalSmile = postDetailObj.optString("smile_reaction","0");
String postTotalLaugh = postDetailObj.optString("laugh_reaction","0");
String postTotalSad = postDetailObj.optString("sad_reaction","0");
String postTotalLove = postDetailObj.optString("love_reaction","0");
String postTotalShock = postDetailObj.optString("shock_reaction","0");
int totalPostFiles = Integer.parseInt(postTotalPost);
int postArrLength = postFilesArr.length();
String postImageUrl = null;
String postMusicUrl = null;
String commonUrl = "http://serverName.com/";
if(postArrLength >= 1){
JSONObject dataFilesListObj = postFilesArr.optJSONObject(0);
// System.out.println("post files full data... : " + dataFilesListObj);
String postFileId = dataFilesListObj.optString("id");
postImageUrl = dataFilesListObj.optString("image_file_path");
postMusicUrl = dataFilesListObj.optString("music_file_path");
System.out.println("post files full data... : " + dataFilesListObj);
}
System.out.println("post files full data... : " + commonUrl+postMusicUrl);
System.out.println("post files full data... : " + commonUrl+postImageUrl);
PostList postList = new PostList();
postList.setId(postId);
postList.setTitle(postTitle);
postList.setTotalPost(""+dataArrLength);
postList.setTotalView(postTotalViews);
postList.setTotalReaction(postTotalReaction);
postList.setMusicPath(commonUrl+postMusicUrl);
postList.setImagePath(commonUrl+postImageUrl);
if(postImageUrl == null){
postList.setImagePath("https://amazonBucket.s3.location.amazonaws.com/images/pic1.jpg");
}
postList.setUserId(userId);
postList.setUserName(userName);
postList.setPostDataObject(arrayResponse);
postListGlobal.add(postList);
Log.d(TAG, "Total Posts: "+dataListObj);
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG, "Post Data Error1: "+e);
Toast.makeText(getActivity(), "File now found", Toast.LENGTH_LONG).show();
loading = false;
}
}
} catch (Exception e){
e.printStackTrace();
Log.d(TAG, "Post Data Error2: "+e);
Toast.makeText(getActivity(), R.string.server_error, Toast.LENGTH_LONG).show();
loading = false;
}
}else{
try {
Toast.makeText(getActivity(), new JSONObject(jsonString).getString("Message"), Toast.LENGTH_LONG).show();
} catch (JSONException ex) {
ex.printStackTrace();
Log.d(TAG, "Post Data Error3: "+ex);
Toast.makeText(getActivity(), R.string.server_error, Toast.LENGTH_SHORT).show();
}
loading = false;
}
// refreshing recycler view
homeFragmentAdapter.removeNull();
homeFragmentAdapter.addData(postListGlobal);
homeFragmentAdapter.notifyDataSetChanged();
// save in local memory
// saveArrayList(postListGlobal, "postListGlobal");
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG, "Post Data Error4: "+e);
}
loading = true;
homeFragmentAdapter.notifyDataSetChanged();
swipeMore.setRefreshing(false);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity(), "onErrorResponse: "+ error, Toast.LENGTH_SHORT).show();
swipeMore.setRefreshing(false);
loading = true;
homeFragmentAdapter.notifyDataSetChanged();
postLoader.setVisibility(View.VISIBLE);
loading = false;
Log.d(TAG, "Post Data Error5: "+error);
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
String finalToken = "Bearer "+token;
params.put("Authorization", finalToken);
params.put("Content-Type", "application/json");
return params;
}
};
// Add the request to the RequestQueue.
queue.add(cacheRequest);
}
private class CacheRequest extends Request<NetworkResponse> {
private final Response.Listener<NetworkResponse> mListener;
private final Response.ErrorListener mErrorListener;
public CacheRequest(int method, String url, Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) {
super(method, url, errorListener);
this.mListener = listener;
this.mErrorListener = errorListener;
}
#Override
protected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) {
Cache.Entry cacheEntry = HttpHeaderParser.parseCacheHeaders(response);
if (cacheEntry == null) {
cacheEntry = new Cache.Entry();
}
final long cacheHitButRefreshed = 3 * 60 * 1000; // in 3 minutes cache will be hit, but also refreshed on background
final long cacheExpired = 24 * 60 * 60 * 1000; // in 24 hours this cache entry expires completely
long now = System.currentTimeMillis();
final long softExpire = now + cacheHitButRefreshed;
final long ttl = now + cacheExpired;
cacheEntry.data = response.data;
cacheEntry.softTtl = softExpire;
cacheEntry.ttl = ttl;
String headerValue;
headerValue = response.headers.get("Date");
if (headerValue != null) {
cacheEntry.serverDate = HttpHeaderParser.parseDateAsEpoch(headerValue);
}
headerValue = response.headers.get("Last-Modified");
if (headerValue != null) {
cacheEntry.lastModified = HttpHeaderParser.parseDateAsEpoch(headerValue);
}
cacheEntry.responseHeaders = response.headers;
return Response.success(response, cacheEntry);
}
#Override
protected void deliverResponse(NetworkResponse response) {
mListener.onResponse(response);
}
#Override
protected VolleyError parseNetworkError(VolleyError volleyError) {
Log.d(TAG, "Post Data volleyError: "+volleyError);
return super.parseNetworkError(volleyError);
}
#Override
public void deliverError(VolleyError error) {
mErrorListener.onErrorResponse(error);
}
}
}
and Adapter Class
package com.example.ProjectName;
public class HomeFragmentAdapter extends RecyclerView.Adapter <HomeFragmentAdapter.HomeViewHolder>{
// private ArrayList<Integer> dataList;
private List<PostList> postListGlobal;
int VIEW_TYPE_LOADING;
int VIEW_TYPE_ITEM;
Context context;
private RecyclerViewItemListener callback;
FFmpeg ffmpeg;
String callingPage;
public HomeFragmentAdapter(List<PostList> postListGlobal, RecyclerViewItemListener callback, String callingPage) {
this.postListGlobal = postListGlobal;
this.callback = callback;
this.callingPage = callingPage;
// setHasStableIds(true);
}
#NonNull
#Override
public HomeFragmentAdapter.HomeViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View root = null;
context = parent.getContext();
root = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_home_tile_list, parent, false);
return new DataViewHolder(root);
}
#Override
public void onBindViewHolder(#NonNull HomeFragmentAdapter.HomeViewHolder holder, int position) {
if (holder instanceof DataViewHolder) {
final PostList postList = postListGlobal.get(position);
holder.postTitle.setText(postList.getTitle());
holder.postWatch.setText(postList.getTotalView());
holder.postReaction.setText(postList.getTotalReaction());
String imageUrl = postList.getImagePath();
// String imageUrl = Constant.SERVER_URL+"/"+postList.getImagePath();
String musicUrl = postList.getMusicPath();
// String musicUrl = Constant.SERVER_URL+"/"+postList.getMusicPath();
Log.d(TAG, "Post url: "+imageUrl+" -- "+musicUrl);
// int totalMusicTime = getDurationVal(musicUrl, "second");
holder.postTime.setText(postList.getTotalPost());
holder.thumbnail.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
callback.onItemClicked(position);
Log.d("homeView", "screenName : "+callingPage);
if(callingPage.equals("home")){
Log.d("homeView", "screenName : "+position);
Intent intent = new Intent(context, MainViewActivity.class);
intent.putExtra("loginFrom", "homeView");
intent.putExtra("postDataObj", postList.getPostDataObject().toString());
intent.putExtra("postPosition", ""+position);
intent.putExtra("tabId", "1");
context.startActivity(intent);
}
}
});
Drawable mDefaultBackground = context.getResources().getDrawable(R.drawable.influencers);
CircularProgressDrawable circularProgressDrawable = new CircularProgressDrawable(context);
circularProgressDrawable.setStrokeWidth(5f);
Glide.with(context)
.load(imageUrl)
.listener(new RequestListener<Drawable>() {
#Override
public boolean onLoadFailed(#Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
// progressBar.setVisibility(View.GONE);
return false;
}
#Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
// progressBar.setVisibility(View.GONE);
return false;
}
})
.error(mDefaultBackground)
.into(holder.thumbnail);
}else{
//Do whatever you want. Or nothing !!
}
}
#Override
public int getItemCount() {
return postListGlobal.size();
}
class DataViewHolder extends HomeViewHolder {
public DataViewHolder(View itemView) {
super(itemView);
}
}
class ProgressViewHolder extends HomeViewHolder {
public ProgressViewHolder(View itemView) {
super(itemView);
}
}
class HomeViewHolder extends RecyclerView.ViewHolder {
public TextView postTitle, postTime, postWatch, postReaction;
public ImageView thumbnail;
public HomeViewHolder(View itemView) {
super(itemView);
postTitle = itemView.findViewById(R.id.post_title);
postTime = itemView.findViewById(R.id.total_time);
postWatch = itemView.findViewById(R.id.total_watch);
postReaction = itemView.findViewById(R.id.total_reaction);
thumbnail = itemView.findViewById(R.id.thumbnail);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
public void addNullData() {
}
public void removeNull() {
notifyItemRemoved(postListGlobal.size());
}
public void addData(List<PostList> postLists) {
postListGlobal.addAll(postLists);
notifyDataSetChanged();
}
}
After trying everything, I was still not able to resolve the issue. Any help/suggestions are welcome. Let me know If I left out any needed code--if so I can update it here.
`postListGlobal.add(postList);` below this line add ` homeFragmentAdapter.notifyDataSetChanged();` and remove ` homeFragmentAdapter.removeNull(); homeFragmentAdapter.addData(postListGlobal);homeFragmentAdapter.notifyDataSetChanged();` this code.Because in this case list added twice without notifying datasetchange check with your code by removing this.
postListGlobal.clear(); just clear tha arraylist before add .
postListGlobal.clear() before adding new list to the adapter.
And then notifyDataSetChanged() to let adapter know of the changes.
I am new to android development.I have a recyclerview with Viewholder for displaying photo.I have implement like feature in my app but only problem that I am facing is when I add a like on the photo the like does not show on photo I liked instead it is showing like on another photo that is down below,when I see in firebase database it looks fine but it does not display in the right position in recycler view.
I think it is not updating position how can I solve this?
this is my adapter class
#Override
public void onBindViewHolder(#NonNull final RecyclerView.ViewHolder holder, final int position) {
// mHolder = holder;
photo = moviesList.get(position);
// final VideoHolder viewHolder2 = (VideoHolder)holder;
int viewType = getItemViewType(holder.getAdapterPosition());
switch ( viewType ) {
case IMAGE_TYPE:
PhotoHolder photoview = (PhotoHolder) holder;
mPhotoHolder = photoview;
getCurrentUsername();
getLikesPhotoString();
final ImageLoader imageLoader = ImageLoader.getInstance();
imageLoader.displayImage(getItem(position).getImage_path(),photoview.image);
photoview.mHeart.setOnLikeListener(new OnLikeListener() {
#Override
public void liked(LikeButton likeButton) {
addNewPhotolike(mPhotoHolder);
}
#Override
public void unLiked(LikeButton likeButton) {
removePhotolike(mPhotoHolder);
}
});
photoview.Star.setOnLikeListener(new OnLikeListener() {
#Override
public void liked(LikeButton likeButton) {
}
#Override
public void unLiked(LikeButton likeButton) {
}
});
break;
case VIDEO_TYPE:
final VideoHolder viewHolder2 = (VideoHolder)holder;
mVideoHolder = viewHolder2;
break;
}
}
#Override
public int getItemCount() {
return moviesList.size();
}
public Photo getItem(int position) {
return moviesList.get(position);
}
#Override
public int getItemViewType ( int position ) {
int viewType;
if (moviesList.get(position).getType_post().contains("Photo")) {
viewType = IMAGE_TYPE;
} else{
viewType = VIDEO_TYPE;
}
return viewType;
}
this is were photo like is added to firebase
private void addNewPhotolike(TestAdapter.PhotoHolder holder, final int position){
Log.d(TAG, "addNewlike: adding new like ");
String newLikeID = mReference.push().getKey();
Likes likes = new Likes();
likes.setUser_id(FirebaseAuth.getInstance().getCurrentUser().getUid());
mReference.child(mContext.getString(R.string.dbname_photos))
.child(getItem(position).getPhoto_id())
.child(mContext.getString(R.string.field_likes))
.child(newLikeID)
.setValue(likes);
mReference.child(mContext.getString(R.string.dbname_user_photos))
.child(getItem(position).getUser_id())
.child(getItem(position).getPhoto_id())
.child(mContext.getString(R.string.field_likes))
.child(newLikeID)
.setValue(likes);
holder.mHeartPhoto.setLiked(true);
HashMap<String ,String> notificationData = new HashMap<>();
notificationData.put("from",FirebaseAuth.getInstance().getCurrentUser().getUid());
notificationData.put("type","likes");
notificationData.put("photo_desc",getItem(position).getDescription());
holder.mNotification.child(getItem(position).getUser_id()).push().setValue(notificationData).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
// getLikesString(mHolder);
getLikesPhotoString(mPhotoHolder,position);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
// getLikesString(mHolder);
getLikesPhotoString(mPhotoHolder,position);
}
});
}
This is my code where like is retrieved from firebase and shown in text.
private void getLikesPhotoString(final TestAdapter.PhotoHolder holder, final int postion){
Log.d(TAG, "getLikesString: getting likes string");
try{
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
reference.keepSynced(true);
Query query = reference
.child(mContext.getString(R.string.dbname_photos))
.child(getItem(postion).getPhoto_id())
.child(mContext.getString(R.string.field_likes));
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
holder.usersPhoto = new StringBuilder();
for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()){
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
Query query = reference
.child(mContext.getString(R.string.dbname_users))
.orderByChild(mContext.getString(R.string.field_user_id))
.equalTo(singleSnapshot.getValue(Likes.class).getUser_id());
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()){
Log.d(TAG, "onDataChange: found like: " +
singleSnapshot.getValue(User.class).getUsername());
holder.usersPhoto.append(singleSnapshot.getValue(User.class).getUsername());
holder.usersPhoto.append(",");
}
String[] splitUsers = holder.usersPhoto.toString().split(",");
if( holder.usersPhoto.toString().contains(currentUsername + ",")){
holder.likephotobycurrentUser = true;
}else{
holder.likephotobycurrentUser = false;
}
Log.d(TAG, "onDataChange: likes string: " + holder.mLIkePhotoString);
// setupwidjets();
int length = splitUsers.length;
if(length == 1){
holder.mLIkePhotoString = "Liked by " + splitUsers[0];
}
else if(length == 2){
holder.mLIkePhotoString = "Liked by " + splitUsers[0]
+ " and " + splitUsers[1];
}
else if(length == 3){
holder.mLIkePhotoString = "Liked by " + splitUsers[0]
+ ", " + splitUsers[1]
+ " and " + splitUsers[2];
}
else if(length == 4){
holder.mLIkePhotoString = "Liked by " + splitUsers[0]
+ ", " + splitUsers[1]
+ ", " + splitUsers[2]
+ " and " + splitUsers[3];
}
else if(length > 4){
holder.mLIkePhotoString = "Liked by " + splitUsers[0]
+ ", " + splitUsers[1]
+ ", " + splitUsers[2]
+ " and " + (splitUsers.length - 3) + " others";
}
Log.d(TAG, "onDataChange: likes string: " + holder.mLIkePhotoString);
//setup likes string
// setupLikePhotostring(holder, holder.mLIkePhotoString);
holder.mHeartPhoto.setLiked(true);
if (holder.likephotobycurrentUser){
holder.mHeartPhoto.setLiked(true);
}else {
holder.mHeartPhoto.setLiked(false);
}
holder.likes.setText(holder.mLIkePhotoString);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
if(!dataSnapshot.exists()){
holder.mLIkePhotoString = "";
holder.likephotobycurrentUser = false;
//setupwidjets();
// setupLikePhotostring(holder,holder.mLIkePhotoString);
if (holder.likephotobycurrentUser){
holder.mHeartPhoto.setLiked(true);
}else {
holder.mHeartPhoto.setLiked(false);
}
holder.likes.setText(holder.mLIkePhotoString);
holder.mHeartPhoto.setLiked(false);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}catch (NullPointerException e){
Log.e(TAG, "removeStar: NullPointer"+e.getMessage());
holder.mLIkePhotoString = "";
holder.likephotobycurrentUser = false;
// setupLikePhotostring(mPhotoHolder,holder.mLIkePhotoString);
if (holder.likephotobycurrentUser){
holder.mHeartPhoto.setLiked(true);
}else {
holder.mHeartPhoto.setLiked(false);
}
holder.likes.setText(holder.mLIkePhotoString);
}
}
Change this line
photo = moviesList.get(holder.getAdapterPosition());
to
photo = moviesList.get(position);
where position variable is same as we got in below function
public void onBindViewHolder(#NonNull final RecyclerView.ViewHolder holder, final int position);
And also change holder.getAdapterPosition() to position in onBindViewHolder(...) function.
I am making classified marketplace android app. So, I have to show ads or post done by people on my home page, all is working and I am getting all my post on postman but not on my recycleview.
public class SearchFragment extends Fragment {
private static final String TAG = "SearchFragment";
private static final String BASE_URL = "http://35.188.133.114//elasticsearch/posts/post/";
private static final int NUM_GRID_COLUMNS = 2;
private static final int GRID_ITEM_MARGIN = 5;
//widgets
private ImageView mFilters;
private EditText mSearchText;
private FrameLayout mFrameLayout;
//vars
private String mElasticSearchPassword;
private String mPrefCity;
private String mPrefStateProv;
//private String mPrefCountry;
private String mPrefCollege;
private ArrayList<Post> mPosts;
private RecyclerView mRecyclerView;
private PostListAdapter mAdapter;
private ListView listView;
private String currentuser;
private String user;
private ImageView filter;
ArrayList<Card> list = new ArrayList<>();
FloatingActionButton fab;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_search, container, false);
mFilters = (ImageView) view.findViewById(R.id.ic_search);
mSearchText = (EditText) view.findViewById(R.id.input_search);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
mFrameLayout = (FrameLayout) view.findViewById(R.id.container);
filter = (ImageView) view.findViewById(R.id.filter);
currentuser = FirebaseAuth.getInstance().getUid();
filter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getActivity(),FiltersActivity.class);
startActivity(intent);
}
});
getElasticSearchPassword();
welcome();
init();
return view;
}
private void setupPostsList(){
RecyclerViewMargin itemDecorator = new RecyclerViewMargin(GRID_ITEM_MARGIN, NUM_GRID_COLUMNS);
mRecyclerView.addItemDecoration(itemDecorator);
GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), NUM_GRID_COLUMNS);
mRecyclerView.setLayoutManager(gridLayoutManager);
mAdapter = new PostListAdapter(getActivity(), mPosts);
mRecyclerView.setAdapter(mAdapter);
// CustomListAdapter adapter = new CustomListAdapter(getActivity(), R.layout.card_layout_main, list);
}
private void welcome() {
if (!currentuser.equals("")) {
mPosts = new ArrayList<Post>();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
ElasticSearchAPI searchAPI = retrofit.create(ElasticSearchAPI.class);
HashMap<String, String> headerMap = new HashMap<String, String>();
headerMap.put("Authorization", Credentials.basic("user", mElasticSearchPassword));
// String searchString = "*";
/* if(!mSearchText.equals("")){
searchString = searchString + mSearchText.getText().toString() + "*";
}*/
/* if(!mPrefCity.equals("")){
searchString = searchString + " city:" + mPrefCity;
}
if(!mPrefStateProv.equals("")){
searchString = searchString + " state_province:" + mPrefStateProv;
}*/
/* if(!mPrefCollege.equals("")){
searchString = searchString + " college:" + mPrefCollege;
}*/
/*if(!currentuser.equals("")){
searchString = searchString + " user_id:" + currentuser;
}*/
Call<HitsObject> call = searchAPI.search(headerMap, "AND", "*");
call.enqueue(new Callback<HitsObject>() {
#Override
public void onResponse(Call<HitsObject> call, Response<HitsObject> response) {
HitsList hitsList = new HitsList();
String jsonResponse = "";
try {
Log.d(TAG, "onResponse: server response: " + response.toString());
if (response.isSuccessful()) {
hitsList = response.body().getHits();
} else {
jsonResponse = response.errorBody().string();
}
Log.d(TAG, "onResponse: hits: " + hitsList);
for (int i = 0; i < hitsList.getPostIndex().size(); i++) {
Log.d(TAG, "onResponse: data: " + hitsList.getPostIndex().get(i).getPost().toString());
mPosts.add(hitsList.getPostIndex().get(i).getPost());
}
Log.d(TAG, "onResponse: size: " + mPosts.size());
//setup the list of posts
setupPostsList();
} catch (NullPointerException e) {
Log.e(TAG, "onResponse: NullPointerException: " + e.getMessage());
} catch (IndexOutOfBoundsException e) {
Log.e(TAG, "onResponse: IndexOutOfBoundsException: " + e.getMessage());
} catch (IOException e) {
Log.e(TAG, "onResponse: IOException: " + e.getMessage());
}
}
#Override
public void onFailure(Call<HitsObject> call, Throwable t) {
Log.e(TAG, "onFailure: " + t.getMessage());
Toast.makeText(getActivity(), "search failed", Toast.LENGTH_SHORT).show();
}
});
}
// return false;
}
private void init(){
mFilters.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mPosts = new ArrayList<Post>();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
ElasticSearchAPI searchAPI = retrofit.create(ElasticSearchAPI.class);
HashMap<String, String> headerMap = new HashMap<String, String>();
headerMap.put("Authorization", Credentials.basic("user", mElasticSearchPassword));
String searchString = "";
if(!mSearchText.equals("")){
searchString = searchString + mSearchText.getText().toString() + "*";
}
/* if(!mPrefCity.equals("")){
searchString = searchString + " city:" + mPrefCity;
}
if(!mPrefStateProv.equals("")){
searchString = searchString + " state_province:" + mPrefStateProv;
}*/
if(!mPrefCollege.equals("")){
searchString = searchString + " college:" + mPrefCollege;
}
/*if(!currentuser.equals("")){
searchString = searchString + " user_id:" + currentuser;
}*/
Call<HitsObject> call = searchAPI.search(headerMap, "AND", searchString);
call.enqueue(new Callback<HitsObject>() {
#Override
public void onResponse(Call<HitsObject> call, Response<HitsObject> response) {
HitsList hitsList = new HitsList();
String jsonResponse = "";
try{
Log.d(TAG, "onResponse: server response: " + response.toString());
if(response.isSuccessful()){
hitsList = response.body().getHits();
}else{
jsonResponse = response.errorBody().string();
}
Log.d(TAG, "onResponse: hits: " + hitsList);
for(int i = 0; i < hitsList.getPostIndex().size(); i++){
Log.d(TAG, "onResponse: data: " + hitsList.getPostIndex().get(i).getPost().toString());
mPosts.add(hitsList.getPostIndex().get(i).getPost());
}
Log.d(TAG, "onResponse: size: " + mPosts.size());
//setup the list of posts
setupPostsList();
}catch (NullPointerException e){
Log.e(TAG, "onResponse: NullPointerException: " + e.getMessage() );
}
catch (IndexOutOfBoundsException e){
Log.e(TAG, "onResponse: IndexOutOfBoundsException: " + e.getMessage() );
}
catch (IOException e){
Log.e(TAG, "onResponse: IOException: " + e.getMessage() );
}
}
#Override
public void onFailure(Call<HitsObject> call, Throwable t) {
Log.e(TAG, "onFailure: " + t.getMessage() );
Toast.makeText(getActivity(), "search failed", Toast.LENGTH_SHORT).show();
}
});
}
// return false;
});
}
welcome() method is not called as i am not able to see any post but init() method is working and showing all the post when clicking on search button. And both methods are using same code, the only difference of the query that I am making, do not know why welcome() method is not showing any post.
Actually, Your method is called from onCreate() but your condition (!currentuser.equals("") is return false.
See the value of currentuser = FirebaseAuth.getInstance().getUid();
Only if you authenticate the user,then you will have this as not null else it will be empty or null.
This is issue with Firbase issue, Please check the firebase instance is configured and initialized properly in your application class. Then you should not able to get currentUser == "".
Firebase will return 401/410 error code incase of invalid user token / authentication with invalid user information.
We are creating a chat application using openfire, smack. In that there is a chatscreen where users can send and receive messages and media files. For storing messages we are using Realm as local db. I want to show the progress of files during upload of files.
My Upload file code is :
public void firebasestorageMeth(final String msg, final String path, final String filetype, final String mykey, final String otheruserkey, final String username) {
StorageReference riversRef = STORAGE_REFERENCE.child(mykey).child("files").child(GetTimeStamp.timeStampDate());
final String timestampdate = GetTimeStamp.timeStampDate();
final String timestamptime = GetTimeStamp.timeStampTime();
final long id = GetTimeStamp.Id();
ChatMessageRealm cmr = new ChatMessageRealm(mykey + otheruserkey, otheruserkey, msg, mykey, timestamptime, timestampdate, filetype, String.valueOf(id), "0", "",path);
ChatHelper.addChatMesgRealmMedia1(cmr, this, mykey, otheruserkey);
sendBroadcast(new Intent().putExtra("reloadchatmediastatus", MEDIA_STARTING).putExtra("reloadchatmediaid", String.valueOf(id)).putExtra("reloadchatmedialocalurl", path).setAction("reloadchataction"));
Log.d(TAG, cmr.getChatref()+cmr.getMsgid()+cmr.getMsgstring()+"file path extension upload file" + path);
riversRef.putFile(Uri.fromFile(new File(path)))
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
umpref.setUri(String.valueOf(id), path);
Uri downloadUrl = taskSnapshot.getDownloadUrl();
Log.d(TAG, "file uploaded" + downloadUrl);
ChatMessageRealm cmr = new ChatMessageRealm(mykey + otheruserkey, otheruserkey, msg, mykey, timestamptime, timestampdate, filetype, String.valueOf(id), "1", String.valueOf(downloadUrl),path);
ChatHelper.addChatMesgRealmMedia1(cmr, getApplicationContext(), mykey, otheruserkey);
sendBroadcast(new Intent().putExtra("reloadchatmediastatus", MEDIA_SUCCESS).putExtra("reloadchatmediaid", String.valueOf(id)).putExtra("reloadchatmediaurl", String.valueOf(downloadUrl)).putExtra("reloadchatmedialocalurl", path).setAction("reloadchataction"));
Toast.makeText(getApplicationContext(), "File Uploaded ", Toast.LENGTH_LONG).show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
sendBroadcast(new Intent().putExtra("reloadchatmediastatus", MEDIA_FAILED).putExtra("reloadchatmediaid", String.valueOf(id)).putExtra("reloadchatmedialocalurl", path).setAction("reloadchataction"));
exception.printStackTrace();
}
})
.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
int progress = (int) ((100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount());
sendBroadcast(new Intent().putExtra("reloadchatmediastatus", progress + " ").putExtra("reloadchatmediaid", String.valueOf(id)).putExtra("reloadchatmedialocalurl", path).setAction("reloadchataction"));
}
});
}
The chatadapter code is :
public class ChatAdapter1 extends RecyclerView.Adapter<ChatAdapter1.MyViewHolder> {
ArrayList<ChatMessageRealm> mList = new ArrayList<>();
private Context context;
private UserSession session;
public static final int SENDER = 0;
public static final int RECIPIENT = 1;
String TAG = "ChatAdapter1";
public ChatAdapter1(ArrayList<ChatMessageRealm> list, Context context) {
this.mList = list;
this.context = context;
session = new UserSession(context);
}
#Override
public int getItemViewType(int position) {
if (mList.get(position).getSenderjid().matches(session.getUserKey())) {
return SENDER;
} else {
return RECIPIENT;
}
}
#Override
public int getItemCount() {
return mList.size();
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
switch (viewType) {
case SENDER:
View viewSender = inflater.inflate(R.layout.row_chats_sender, viewGroup, false);
viewHolder = new MyViewHolder(viewSender);
break;
case RECIPIENT:
View viewRecipient = inflater.inflate(R.layout.row_chats_receiver, viewGroup, false);
viewHolder = new MyViewHolder(viewRecipient);
break;
}
return (MyViewHolder) viewHolder;
}
#Override
public void onBindViewHolder(final ChatAdapter1.MyViewHolder holder, int position) {
final ChatMessageRealm comment = mList.get(position);
holder.setIsRecyclable(false);
// holder.otherSender_sender.setText(comment.getSenderjid());
holder.otherSender_Timestamp.setText(comment.getSendertime() + "," + comment.getSenderdate());
// holder.status.setVisibility(View.GONE);
switch (comment.getMsgtype()) {
case "text":
// holder.btndown.setVisibility(View.GONE);
String decryptedmsg = comment.getMsgstring();
holder.commentString.setText(decryptedmsg);
// holder.photo.setVisibility(View.GONE);
break;
case "photo":
Glide.clear(holder.imgchat);
holder.imgchat.setVisibility(View.VISIBLE);
holder.progress.setVisibility(View.VISIBLE);
if (getItemViewType(position) == SENDER) {
// holder.btndown.setVisibility(View.GONE);
// holder.btnopen.setVisibility(View.VISIBLE);
try {
Glide.with(context).load(comment.getMsglocalurl()).into(holder.imgchat);
}catch (Exception e){
e.printStackTrace();
}
}
break;
}
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView otherSender_Timestamp, commentString,progress;
public ImageView imgchat;
public Button btndown, btnopen;
public MyViewHolder(View itemView) {
super(itemView);
otherSender_Timestamp = (TextView) itemView.findViewById(R.id.meSender_TimeStamp);
commentString = (TextView) itemView.findViewById(R.id.commentString);
progress = (TextView) itemView.findViewById(R.id.mediaprogress);
imgchat = (ImageView) itemView.findViewById(R.id.imgchat);
btndown = (Button) itemView.findViewById(R.id.btndown);
btnopen = (Button) itemView.findViewById(R.id.btnopen);
}
}
}
ChatActivity code is:
public class ChatActivity extends ToadoBaseActivity {
private EditText typeComment;
private ImageButton sendButton, attachment, takephoto;
Intent intent;
private RecyclerView recyclerView;
DatabaseReference dbChat;
private String otheruserkey;
LinearLayoutManager linearLayoutManager;
private MarshmallowPermissions marshmallowPermissions;
private ArrayList<String> mResults = new ArrayList<>();
private ActionMode actionMode;
UploadFileService uploadFileService;
boolean mServiceBound = false;
SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy hh:mm aa");
private ChatAdapter1 mAdapter;
LinkedHashSet<ChatMessageRealm> uniqueStrings = new LinkedHashSet<ChatMessageRealm>();
private ArrayList<ChatMessageRealm> chatList = new ArrayList<>();
private ArrayList<String> chatListIds = new ArrayList<>();
String username, mykey;
private UserSession session;
String receiverToken = "nil";
boolean clicked;
LinearLayout layoutToAdd;
LinearLayout commentView;
private ChildEventListener dbChatlistener;
ImageButton photoattach, videoattach;
Uri videoUri;
public String dbTableKey;
EncryptUtils encryptUtils = new EncryptUtils();
private ImageButton imgdocattach;
private ImageButton locattach;
private LinearLayout spamView;
TextView tvTitle;
ImageView imgprof;
private ArrayList<String> imagesPathList;
private final int PICK_IMAGE_MULTIPLE = 199;
private ProgressBar progressBar;
UserMediaPrefs umprefs;
private Boolean mBounded;
private String TAG = "ChatActivity";
// AbstractXMPPConnection connection;
Realm mRealm;
Boolean chatexists;
private String otherusername;
private String profpic;
private MyXMPP2 myxinstance;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat1);
session = new UserSession(this);
mykey = session.getUserKey();
// connection = MyXMPP2.getInstance(this,).getConn();
mRealm = Realm.getDefaultInstance();
checkChatRef(otheruserkey);
clicked = false;
layoutToAdd = (LinearLayout) findViewById(R.id.attachmentpopup);
marshmallowPermissions = new MarshmallowPermissions(this);
spamView = (LinearLayout) findViewById(R.id.spamView);
umprefs = new UserMediaPrefs(this);
//get these 2 things from notifications also
intent = getIntent();
otheruserkey = intent.getStringExtra("otheruserkey");
otherusername = intent.getStringExtra("otherusername");
profpic = intent.getStringExtra("profpic");
System.out.println("recevier token chat act oncreate" + otheruserkey);
imgprof = (ImageView) findViewById(R.id.icon_profile);
tvTitle = (TextView) findViewById(R.id.tvTitle);
tvTitle.setText(otherusername);
commentView = (LinearLayout) findViewById(R.id.commentView);
progressBar = (ProgressBar) findViewById(R.id.progress);
typeComment = (EditText) findViewById(R.id.typeComment);
sendButton = (ImageButton) findViewById(R.id.sendButton);
attachment = (ImageButton) findViewById(R.id.attachment);
takephoto = (ImageButton) findViewById(R.id.takephoto);
photoattach = (ImageButton) findViewById(R.id.photoattach);
imgdocattach = (ImageButton) findViewById(R.id.docattach);
videoattach = (ImageButton) findViewById(R.id.videoattach);
locattach = (ImageButton) findViewById(R.id.locationattach);
myxinstance = MyXMPP2.getInstance(ChatActivity.this, getString(R.string.server), mykey);
mAdapter = new ChatAdapter1(chatList, this);
recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(mAdapter);
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println(mykey + " chat created " + otheruserkey);
ChatMessageRealm cm = null;
if (!typeComment.getText().toString().matches("")) {
cm = new ChatMessageRealm(mykey + otheruserkey, otheruserkey, typeComment.getText().toString(), mykey, GetTimeStamp.timeStampTime(), GetTimeStamp.timeStampDate(), "text", String.valueOf(GetTimeStamp.Id()), "1");
}
if (cm != null)
myxinstance.sendMessage(cm);
loadData();
typeComment.setText("");
}
});
attachment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (layoutToAdd.getVisibility() == View.VISIBLE)
layoutToAdd.setVisibility(View.GONE);
else
layoutToAdd.setVisibility(View.VISIBLE);
}
});
takephoto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
dispatchTakePictureIntent();
} catch (ActivityNotFoundException anfe) {
anfe.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
#Override
protected void onResume() {
super.onResume();
mykey = session.getUserKey();
username = session.getUsername();
loadData();
}
private void loadData() {
Sort sort[] = {Sort.ASCENDING};
String[] fieldNames = {"msgid"};
RealmResults<ChatMessageRealm> shows = mRealm.where(ChatMessageRealm.class).equalTo("chatref", mykey + otheruserkey).findAllSorted(fieldNames, sort);
if (shows.size() > 0) {
Log.d(TAG, shows.size() + "LOAD DATA CALLED " + shows.get(shows.size() - 1).getMsgstring());
for (ChatMessageRealm cm : shows) {
if (!chatList.contains(cm)) {
chatList.add(cm);
}
if (!chatListIds.contains(cm.getMsgid())) {
chatListIds.add(cm.getMsgid());
}
mAdapter.notifyDataSetChanged();
}
mAdapter.notifyDataSetChanged();
recyclerView.scrollToPosition(chatList.size() - 1);
}
}
private void checkChatRef(String otheruserkey) {
RealmQuery<ActiveChats> query = mRealm.where(ActiveChats.class);
query.equalTo("otherkey", otheruserkey);
RealmResults<ActiveChats> result1 = query.findAll();
if (result1.size() == 0) {
chatexists = false;
} else {
chatexists = true;
}
System.out.println(result1.size() + "chat exists chatactivity" + chatexists);
}
#Override
protected void onStart() {
super.onStart();
registerReceiver(this.reloadData, new IntentFilter("reloadchataction"));
}
#Override
protected void onStop() {
super.onStop();
if (reloadData != null)
unregisterReceiver(reloadData);
}
private void dispatchTakePictureIntent() throws IOException {
CropImage.activity()
.setGuidelines(CropImageView.Guidelines.ON)
.setMultiTouchEnabled(true)
.start(this);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d(TAG, "request code chatactivity" + requestCode);
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (data != null) {
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
Log.d(TAG, "crop activity");
CropImage.ActivityResult result = CropImage.getActivityResult(data);
if (resultCode == RESULT_OK) {
final String imguri = result.getUri().toString();
try {
final File file = createImageFile();
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
final int chunkSize = 1024; // We'll read in one kB at a time
byte[] imageData = new byte[chunkSize];
InputStream in = null;
OutputStream out = null;
try {
in = getContentResolver().openInputStream(Uri.parse(imguri));
out = new FileOutputStream(file);
int bytesRead;
while ((bytesRead = in.read(imageData)) > 0) {
out.write(Arrays.copyOfRange(imageData, 0, Math.max(0, bytesRead)));
}
String s = file.getAbsolutePath();
Log.d(TAG, "image cropped uri chatact22" + file.getAbsolutePath());
Intent intent = new Intent(ChatActivity.this, ImageComment.class);
intent.putExtra("URI", s);
intent.putExtra("comment_type", "photo");
startImageComment(intent);
} catch (Exception ex) {
Log.e("Something went wrong.", ex.toString());
} finally {
try {
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}.execute();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
private File createImageFile() throws IOException {
// Create an image file name
String imageFileName = "pic-" + GetTimeStamp.timeStamp() + ".jpg";
File image = OpenFile.createFile(this, imageFileName);
// Save a file: path for use with ACTION_VIEW intents
Log.d(TAG, "file createimagefile: " + image.getAbsolutePath());
return image;
}
private void startImageComment(Intent intent) {
Log.d(TAG, "image comment sending" + intent.getStringExtra("URI"));
intent.putExtra("username", username);
intent.putExtra("otheruserkey", otheruserkey);
intent.putExtra("receiverToken", receiverToken);
intent.putExtra("mykey", mykey);
startActivity(intent);
}
BroadcastReceiver reloadData = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getStringExtra("reloadchat") != null) {
Log.d(TAG, " reloading data broadcast receiver" + intent.getStringExtra("reloadchat"));
loadData();
mAdapter.notifyDataSetChanged();
} else if (intent.getStringExtra("reloadchatmediastatus") != null) {
if (intent.getStringExtra("reloadchatmediastatus").matches(MEDIA_STARTING))
loadData();
Log.d(TAG, " reloading data status " + intent.getStringExtra("reloadchatmediastatus"));
Log.d(TAG, " reloading data media id " + intent.getStringExtra("reloadchatmediaid"));
if (!intent.getStringExtra("reloadchatmediastatus").matches(MEDIA_FAILED)) {
final String msgid = intent.getStringExtra("reloadchatmediaid");
String fileprogress = intent.getStringExtra("reloadchatmediastatus");
int ind1 = chatListIds.indexOf(msgid);
Log.d(TAG, ind1 + "chat list broadcast progress " + fileprogress);
Log.d(TAG, "chat list broadcast" + chatListIds.size());
try {
// View ve = linearLayoutManager.findViewByPosition(ind1);
// View v = recyclerView.findViewHolderForAdapterPosition(ind1).itemView;
View v = recyclerView.findViewHolderForLayoutPosition(ind1).itemView;
ChatAdapter1.MyViewHolder holder = (ChatAdapter1.MyViewHolder) recyclerView.getChildViewHolder(v);
holder.commentString.setVisibility(View.VISIBLE);
holder.commentString.setText("file prog " + fileprogress);
mAdapter.notifyDataSetChanged();
Log.d(TAG, holder.getItemViewType() + "," + holder.getLayoutPosition() + "," + holder.commentString.getText().toString() + " VIEW HOLDER? " + v);
} catch (Exception e) {
e.printStackTrace();
}
}
}
if (intent.getStringExtra("reloadchatmediaurl") != null)
Log.d(TAG, " reloading data media url " + intent.getStringExtra("reloadchatmediaurl"));
}
};
}
I am trying to update my recyclerview dynamically in the broadcast receiver- reloadData in ChatActivity.
My logs tell me that i am receiving correct data from the sendbroadcast in the UploadFileService, the problem is in following code inside the broadcast receiver on ChatActivity, it is getting correct data but the data is not showing on the recycler view:
try {
View v = recyclerView.findViewHolderForLayoutPosition(ind1).itemView;
ChatAdapter1.MyViewHolder holder = (ChatAdapter1.MyViewHolder) recyclerView.getChildViewHolder(v);
holder.commentString.setVisibility(View.VISIBLE);
holder.commentString.setText("file prog " + fileprogress);
mAdapter.notifyDataSetChanged();
Log.d(TAG, holder.getItemViewType() + "," + holder.getLayoutPosition() + "," + holder.commentString.getText().toString() + " VIEW HOLDER? " + v);
} catch (Exception e) {
e.printStackTrace();
}
I get correct values , such as:
08-03 19:31:25.240 705-705/com.app.toado D/ChatActivity: 0,30,file prog 34 VIEW HOLDER? android.widget.LinearLayout{ff24ae0 V.E...... ......I. 0,621-660,1380 #7f1100f2 app:id/message_container}
08-03 19:31:26.346 705-705/com.app.toado D/ChatActivity: 0,30,file prog 100 VIEW HOLDER? android.widget.LinearLayout{e8a33ce V.E...... ......I. 0,621-660,1380 #7f1100f2 app:id/message_container}
08-03 19:31:26.347 705-705/com.app.toado D/ChatActivity: 0,30,file prog upload success VIEW HOLDER? android.widget.LinearLayout{e8a33ce V.E...... ......I. 0,621-660,1380 #7f1100f2 app:id/message_container}
I have tried using View ve = linearLayoutManager.findViewByPosition(ind1); and View v = recyclerView.findViewHolderForAdapterPosition(ind1).itemView; but they are also not working. Also tried adding notifydatasetchanged to it.
The try catch is also not throwing any error in the logs.
Can someone please help in figuring out why are the changes not showing on the recycler view but are showing in logs?
Are you sure you're updating the RecyclerView's Adapter from the UI Thread? Whenever you try to update the ViewHolder, you have to be certain you're doing so on the UI or it will not behave as expected.
When the modification to the ViewHolder is changed, check that Looper.myLooper().equals(Looper.getMainLooper());. If it returns false, it means you aren't updating on the UI Thread, the necessary place for all graphical updates to be made.
If this is the case, you just need to make sure that you can synchronize your changes on the UI, using Activity.runOnUiThread(Runnable r);.
I'm trying to update all my Items in a Recyclerview with the SwipeRefreshlayout,
but unfortunately will only the last item be updated, the others remain unchanged.
Here is my relevant code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//LeakCanary.install(this.getApplication());
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(ContextCompat.getColor(this, R.color.colorPrimaryDark));
}
handleArrayList(getApplicationContext(), 0);
Log.d("Arraylist", "" + intentNumber2.size());
recyclerView = (RecyclerView) findViewById(R.id.rv);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setItemAnimator(null);
recyclerView.setHasFixedSize(true);
SimpleAdapter adapter = new SimpleAdapter();
recyclerView.addItemDecoration(new SimpleDividerItemDecoration(this));
recyclerView.setAdapter(adapter);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getBaseContext(), AddReminder.class);
startActivity(intent);
}
});
adapter.notifyItemInserted(cards.size() - 1);
refreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
updateRemainingTime();
refreshLayout.setOnRefreshListener(this);
}
#Override
public void onRefresh() {
updateRemainingTime();
}
//refresh the time remaining on the cards
private void updateRemainingTime() {
if (!cards.isEmpty()) {
for (int i = cards.size()-1; i >= 0; i--) {
Card card = cards.get(i);
String time = card.getCardTime();
String date = card.getCardDate();
Date now = new Date();
Date then = null;
try {
then = sdtf.parse(date + " " + time);
} catch (ParseException e) {
Log.d("PARSEEXCEPTION:", " " + e);
}
String remainingTime = calculate.calcTimeDiff(then.getTime(), now.getTime());
Log.d("Card","Card updated " + remainingTime);
card.cardRemainingTime(remainingTime);
recyclerView.getAdapter().notifyItemChanged(i);
}
refreshLayout.setRefreshing(false);
} else {
refreshLayout.setRefreshing(false);
}
}
My Adapter:
public class SimpleAdapter extends RecyclerView.Adapter<SimpleAdapter.ViewHolder> implements RemoveItem {
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View itemView = inflater.inflate(R.layout.item_main, parent, false);
return new ViewHolder(itemView, this);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Card card = cards.get(position);
holder.setReminderText(card.getCardText());
card_tv2.setText(card.getCardRemainingTime());
holder.setSelectable(true);
}
#Override
public int getItemCount() {
return cards.size();
}
#Override
public void remove(int position) {
cards.remove(position);
Log.d("Main", "removed " + position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, cards.size());
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent1 = new Intent(getBaseContext(), AlarmReceiver.class);
int intentNumber = intentNumber2.get(position);
intentNumber2.remove(position);
Log.d("IntentNumber", "" + intentNumber);
PendingIntent alarmIntent = PendingIntent.getBroadcast(getApplicationContext(), intentNumber, intent1, PendingIntent.FLAG_CANCEL_CURRENT);
alarmIntent.cancel();
alarmManager.cancel(alarmIntent);
File dir = getFilesDir();
File file = new File(dir, "Reminder" + " " + position);
boolean deleted = file.delete();
MainActivity.handleArrayList(getApplicationContext(), 1);
}
public class ViewHolder extends SwappingHolder implements View.OnClickListener, View.OnLongClickListener {
public final LinearLayout background;
public ViewHolder(View itemView, RemoveItem removeItem1) {
super(itemView, multiSelector);
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
itemView.setLongClickable(true);
removeItem = removeItem1;
card_tv = (TextView) itemView.findViewById(R.id.card_tv);
card_tv2 = (TextView) itemView.findViewById(R.id.card_tv2);
card_th = (ImageView) itemView.findViewById(R.id.thumbnail);
card_check = (ImageView) itemView.findViewById(R.id.card_check);
background = (LinearLayout) itemView.findViewById(R.id.background);
}
#Override
public void onClick(View view) {
if (multiSelector.tapSelection(this)) {
background.setSelected(true);
} else {
int position = getAdapterPosition();
String text = "error";
String time = "error";
String date = "error";
String repeat;
boolean repeat2 = false;
String quantity = "error";
String mode = "error";
try {
InputStream inputStream = openFileInput("Reminder" + " " + position);
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
text = bufferedReader.readLine();
time = bufferedReader.readLine();
date = bufferedReader.readLine();
repeat = bufferedReader.readLine();
repeat2 = repeat.equals("true");
quantity = bufferedReader.readLine();
mode = bufferedReader.readLine();
inputStreamReader.close();
bufferedReader.close();
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
Intent intent2 = new Intent(getBaseContext(), ChangeReminder.class);
intent2.putExtra("POSITION", position);
intent2.putExtra("TIME", time);
intent2.putExtra("DATE", date);
intent2.putExtra("TEXT", text);
intent2.putExtra("REPEAT", repeat2);
intent2.putExtra("QUANTITY", quantity);
intent2.putExtra("MODE", mode);
startActivity(intent2);
}
}
#Override
public boolean onLongClick(View view) {
AppCompatActivity activity = MainActivity.this;
activity.startSupportActionMode(mDeleteMode);
multiSelector.setSelectable(true);
multiSelector.setSelected(this, true);
background.setSelected(true);
return true;
}
public void setReminderText(String cardText) {
card_tv.setText(cardText);
ColorGenerator colorGenerator = ColorGenerator.MATERIAL;
TextDrawable drawableBuilder;
String letter = "A";
if (cardText != null && !cardText.isEmpty()) {
letter = cardText.substring(0, 1);
}
int color = colorGenerator.getRandomColor();
drawableBuilder = TextDrawable.builder()
.buildRound(letter, color);
card_th.setImageDrawable(drawableBuilder);
}
}
}
}
Card class:
public class Card implements Serializable {
public int drawable;
private String cardText;
private String cardDate;
private String cardTime;
private String cardRemainingTime;
public void cardText(String cardText) {
this.cardText = cardText;
}
public void cardDate(String cardDate) {
this.cardDate = cardDate;
}
public void cardTime(String cardTime) {
this.cardTime = cardTime;
}
public void cardRemainingTime(String cardRemainingTime) {
this.cardRemainingTime = cardRemainingTime;
}
public String getCardText() {
return cardText;
}
public String getCardDate() {
return cardDate;
}
public String getCardTime() {
return cardTime;
}
public String getCardRemainingTime() {
return cardRemainingTime;
}
}
Edit:
I found out that when I reopen the app, the time correctly updates on all items.
This means there has to be a difference between calling updateRemainingTime from onRefresh and onCreate, but I don't know which. Any help would be appreciated.
Make a change in updateRemainingTime method.
if (!cards.isEmpty()) {
for (int i = cards.size() - 1; i >= 0; i--) {
Card card = cards.get(i);
String time = card.getCardTime();
String date = card.getCardDate();
Date now = new Date();
Date then = null;
try {
then = sdtf.parse(date + " " + time);
} catch (ParseException e) {
Log.d("PARSEEXCEPTION:", " " + e);
}
String remainingTime = calculate.calcTimeDiff(then.getTime(), now.getTime());
Log.d("Card", "Card updated " + remainingTime);
//card.cardRemainingTime(remainingTime);
//replaces to
cards.get(i).cardRemainingTime(remainingTime);
}
List<Card> cardTemp = new ArrayList<>();
cardTemp = cards;
cards.clear();
cards.addAll(cardTemp);
recyclerView.notifyDataSetChanged();
}