I have a Nested Scroll view and inside this, I have a Linear Layout that includes two recycler views. Now the problem is that the first recycler view is not expanding up to its full extent. i.e. there are 5 items in the first recycler view list but it is only showing the first item if I put wrap content. This should expand up to 5 items because of wrap content but it is not working. If I fixed the height to 200DP or 300dp then it started to show more items up to that height. However, I want to show all the items of the first recycler view and then when I scroll it should start second recycler view items after the first recycler view items end.
My layout is:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:layout_marginTop="60dp"
android:orientation="vertical">
<com.sooryen.customview.CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/spacing_normal"
android:text="#string/my_booking_latest_booking_lable"
app:font="avenirltstd_medium" />
<include layout="#layout/layout_divider" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_ongoing_bookings"
android:visibility="visible"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" />
<com.sooryen.customview.CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
android:layout_margin="#dimen/spacing_normal"
android:text="#string/my_booking_past_booking_lable"
app:font="avenirltstd_medium" />
<include layout="#layout/layout_divider" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_past_bookings"
android:visibility="visible"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="false"
android:layout_marginBottom="#dimen/spacing_extra_small"
android:scrollbars="none"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" />
<View
android:layout_width="match_parent"
android:layout_height="150dp" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
Please Help. Where I did something wrong. I tried so many ways from internet but nothing is working. Here is a screenshot of the this screen
The LABEL latest bookings has 5 items but it is only showing one and not expanding up to 5 items. However the second LABEL Past bookings is working perfectly and showing all items when i scroll up to end.
My java file is:
public class MyBookingActivity extends BaseToolBarActivity implements
SwipeRefreshLayout.OnRefreshListener {
int cancelValue;
private SwipeRefreshLayout swipeRefreshLayout;
#BindView(R.id.rv_ongoing_bookings)
RecyclerView mRVOngoingBookings;
private List<MyBookingsApi.ApiResponse.Datum> mCourtDataList = new ArrayList<>();
#BindView(R.id.rv_past_bookings)
RecyclerView mRVPastBookings;
private BaseRecyclerAdapter<MyBookingsApi.ApiResponse.Datum, MyBookingsViewHolder> mBaseRecyclerAdapterMyBookings = new BaseRecyclerAdapter<MyBookingsApi.ApiResponse.Datum, MyBookingsViewHolder>(MyBookingsViewHolder.class, R.layout.layout_list_item_my_bookings) {
#Override
protected void populateViewHolder(MyBookingsViewHolder itemViewHolder, final MyBookingsApi.ApiResponse.Datum model, int position) {
String date = null;
try {
date = new SimpleDateFormat("yyyy/MM/dd", Locale.ENGLISH).format(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH).parse(model.getDate()));
} catch (ParseException e) {
e.printStackTrace();
}
String sessions = "N.A.";
int CancelledValue = model.getCancelled();
if (CancelledValue == 0)
{
itemViewHolder.PaymentYesNo.setText(getString(R.string.booking_detail_no));
itemViewHolder.PaymentYesNo.setBackgroundResource(R.drawable.round_corner_linear_green);
}
else
{
itemViewHolder.PaymentYesNo.setText(getString(R.string.booking_detail_yes));
itemViewHolder.PaymentYesNo.setBackgroundResource(R.drawable.round_corner_linear_red);
}
String paymentConfirmed = model.getPayment_confirmed();
String paymentType = model.getPaymentType();
if (paymentConfirmed.equals("true"))
{
itemViewHolder.PaymentStatus.setText("Confirmed");
}
else
{
itemViewHolder.PaymentStatus.setText("Pending");
}
if (CancelledValue == 0 && paymentConfirmed.equals("false") && paymentType.equals("cash"))
{
itemViewHolder.DepositThisAmount.setText("Deposit " + String.valueOf(model.getDepositAmount()) + " SAR in " +
String.valueOf(model.getDepositTimeAllowed()) + " HRS");
}
else
{
itemViewHolder.DepositThisAmount.setVisibility(View.GONE);
}
if (model.getSession() != null)
sessions = model.getSession();
itemViewHolder.mCustomTextViewCourtBookingTime.setText(date + " " + sessions);
if (getResources().getConfiguration().locale.equals(new Locale("ar"))) {
itemViewHolder.mCustomTextViewCourtPrice.setText(model.getPrice() + " " + "ريال");
itemViewHolder.mCustomTextViewCourtCancellationCutoff.setText("يمكن الغاء الحجز قبل المباراة" + " : " + model.getCancelCutoffTime());
} else {
itemViewHolder.mCustomTextViewCourtPrice.setText(getString(R.string.price, model.getPrice()));
itemViewHolder.mCustomTextViewCourtCancellationCutoff.setText(getString(R.string.cancellation_cutoff, model.getCancelCutoffTime()));
}
String cancelshow = model.getCancelshow();
if (cancelshow.equals("true"))
{
cancelValue = 1;
itemViewHolder.mAppCompatImageViewMoreHoriz.setVisibility(View.VISIBLE);
}
else
{
cancelValue = 0;
itemViewHolder.mAppCompatImageViewMoreHoriz.setVisibility(View.GONE);
}
itemViewHolder.mCustomTextViewCourtName.setText(model.getCourtName());
itemViewHolder.mAppCompatImageViewMoreHoriz.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
PopupMenu popup = new PopupMenu(MyBookingActivity.this, v);
popup.getMenu().add(0, 1, 0, getString(R.string.my_booking_cancel));
//adding click listener
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case 1:
cancelBooking(model.getId());
break;
//case 1:
// deleteBooking(model.getId());
}
return false;
}
});
//displaying the popup
popup.show();
}
});
itemViewHolder.mReaRelativeLayoutMyBooking.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//launchActivity(MyBookingDetailActivity.getActivityIntent(MyBookingActivity.this, model.getId(), "MyBooking", 1));
}
});
itemViewHolder.mAppCompatImageViewRightArrow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
launchActivity(MyBookingDetailActivity.getActivityIntent(MyBookingActivity.this, model.getId(), "MyBooking", 1));
}
});
}
};
private BaseRecyclerAdapter<PastBookingsApi.ApiResponse.Datum, MyPastBookingsViewHolder> mBaseRecyclerAdapterMyPastBookings = new BaseRecyclerAdapter<PastBookingsApi.ApiResponse.Datum, MyPastBookingsViewHolder>(MyPastBookingsViewHolder.class, R.layout.layout_list_item_my_bookings) {
#Override
protected void populateViewHolder(MyPastBookingsViewHolder itemViewHolder, final PastBookingsApi.ApiResponse.Datum model, int position) {
String date = null;
try {
date = new SimpleDateFormat("yyyy/MM/dd", Locale.ENGLISH).format(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH).parse(model.getDate()));
} catch (ParseException e) {
e.printStackTrace();
}
String sessions = "N.A.";
int CancelledValue = model.getCancelled();
if (CancelledValue == 0)
{
itemViewHolder.PaymentYesNo.setText(getString(R.string.booking_detail_no));
itemViewHolder.PaymentYesNo.setBackgroundResource(R.drawable.round_corner_linear_green);
}
else
{
itemViewHolder.PaymentYesNo.setText(getString(R.string.booking_detail_yes));
itemViewHolder.PaymentYesNo.setBackgroundResource(R.drawable.round_corner_linear_red);
}
itemViewHolder.DepositThisAmount.setVisibility(View.GONE);
int paymentConfirmed = model.getPaymentConfirmed();
if (paymentConfirmed == 1)
{
itemViewHolder.PaymentStatus.setText("Confirmed");
}
else
{
itemViewHolder.PaymentStatus.setText("Pending");
}
if (model.getSession() != null)
sessions = model.getSession();
itemViewHolder.mCustomTextViewCourtBookingTime.setText(date + " " + sessions);
if (getResources().getConfiguration().locale.equals(new Locale("ar"))) {
itemViewHolder.mCustomTextViewCourtPrice.setText(model.getPrice() + " " + "ريال");
} else {
itemViewHolder.mCustomTextViewCourtPrice.setText(getString(R.string.price, model.getPrice()));
}
itemViewHolder.mCustomTextViewCourtCancellationCutoff.setText(getString(R.string.cancellation_cutoff, "0"));
itemViewHolder.mCustomTextViewCourtName.setText(model.getCourtName());
itemViewHolder.mAppCompatImageViewMoreHoriz.setVisibility(View.VISIBLE);
itemViewHolder.mAppCompatImageViewMoreHoriz.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
PopupMenu popup = new PopupMenu(MyBookingActivity.this, v);
popup.getMenu().add(0, 1, 0, getString(R.string.notification_delete));
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case 1:
deleteBooking(model.getId());
break;
}
return false;
}
});
popup.show();
}
});
itemViewHolder.mAppCompatImageViewRightArrow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
launchActivity(MyBookingDetailActivity.getActivityIntent(MyBookingActivity.this, model.getId(), "MyBooking", 1));
}
});
itemViewHolder.mReaRelativeLayoutMyBooking.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// launchActivity(MyBookingDetailActivity.getActivityIntent(MyBookingActivity.this, model.getId(), "MyBooking", 1));
}
});
}
};
public static Intent getActivityIntent(Context context) {
return new Intent(context, MyBookingActivity.class);
}
private void cancelBooking(final int id) {
}
private void deleteBooking(final int id) {
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(getString(R.string.title_activity_my_booking));
setUpRecyclerView();
setUpEmptyAdapter();
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);
swipeRefreshLayout.setOnRefreshListener(this);
getMyBooking();
getMyPastBooking();
/*swipeRefreshLayout.post(new Runnable() {
#Override
public void run() {
swipeRefreshLayout.setRefreshing(true);
getMyBooking();
}
}
);*/
}
private void setUpEmptyAdapter() {
mRVPastBookings.setAdapter(new BaseEmptyRecyclerAdapter<EmptyViewHolderRefresh>(EmptyViewHolderRefresh.class, R.layout.layout_place_holderrefresh) {
#Override
protected void populateEmptyViewHolder(EmptyViewHolderRefresh viewHolder) {
viewHolder.mAppCompatImageView.setImageResource(R.drawable.no_booking_place_holder);
viewHolder.mCustomTextViewTitle.setText(R.string.no_bookings_available_title);
viewHolder.mCustomTextViewDescription.setText(R.string.no_bookings_available_description);
viewHolder.refreshText.setText(R.string.swipe);
//viewHolder.mCustomButton.setText(R.string.try_again);
viewHolder.mCustomButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//getMyPastBooking();
}
});
}
});
mRVOngoingBookings.setAdapter(new BaseEmptyRecyclerAdapter<EmptyViewHolderRefresh>(EmptyViewHolderRefresh.class, R.layout.layout_place_holderrefresh) {
#Override
protected void populateEmptyViewHolder(EmptyViewHolderRefresh viewHolder) {
viewHolder.mAppCompatImageView.setImageResource(R.drawable.no_booking_place_holder);
viewHolder.mCustomTextViewTitle.setText(R.string.no_bookings_available_title);
viewHolder.mCustomTextViewDescription.setText(R.string.no_bookings_available_description);
//viewHolder.mCustomButton.setText(R.string.try_again);
viewHolder.refreshText.setText(R.string.swipe);
viewHolder.mCustomButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// getMyBooking();
}
});
}
});
}
private void setUpRecyclerView() {
mRVOngoingBookings.setAdapter(mBaseRecyclerAdapterMyBookings);
DividerItemDecoration mDividerItemDecorationMyBookings = new DividerItemDecoration(this, LinearLayoutManager.VERTICAL);
mDividerItemDecorationMyBookings.setDrawable(ContextCompat.getDrawable(this, R.drawable.divider));
mRVOngoingBookings.addItemDecoration(mDividerItemDecorationMyBookings);
mRVPastBookings.setAdapter(mBaseRecyclerAdapterMyPastBookings);
DividerItemDecoration mDividerItemDecorationMyPastBookings = new DividerItemDecoration(this, LinearLayoutManager.VERTICAL);
mDividerItemDecorationMyPastBookings.setDrawable(ContextCompat.getDrawable(this, R.drawable.divider));
mRVPastBookings.addItemDecoration(mDividerItemDecorationMyPastBookings);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finishWithResultCancel();
}
return super.onOptionsItemSelected(item);
}
#Override
protected int getMenuResource() {
return RESOURCE_NO_MENU;
}
#Override
protected int getLayoutResource() {
return R.layout.activity_my_booking;
}
#Override
public void onResume() {
super.onResume();
registerEventBus();
//getMyBooking();
//getMyPastBooking();
}
#Override
public void onPause() {
super.onPause();
unRegisterEventBus();
}
private void getMyPastBooking() {
/// swipeRefreshLayout.setRefreshing(true);
final ProgressDialog pd = new ProgressDialog(MyBookingActivity.this);
pd.setMessage("Please wait..");
pd.show();
Handler mHandler = new Handler();
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
pd.dismiss();
startApiService(PastBookingsApi.getServiceIntent(MyBookingActivity.this, getToken()));
}
}, 800);
}
private void getMyBooking() {
// swipeRefreshLayout.setRefreshing(true);
final ProgressDialog pd = new ProgressDialog(MyBookingActivity.this);
pd.setMessage("Please wait..");
pd.show();
Handler mHandler = new Handler();
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
pd.dismiss();
startApiService(MyBookingsApi.getServiceIntent(MyBookingActivity.this, getToken()));
}
}, 2000);
//swipeRefreshLayout.setRefreshing(false);
}
#Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(BaseApi.EventBusMessage eventBusMessage) {
switch (eventBusMessage.event) {
case BaseApi.EventBusMessage.EVENT_SHOW_PROGRESS_DIALOG:
showProgressDialog();
break;
case BaseApi.EventBusMessage.EVENT_HIDE_PROGRESS_DIALOG:
hideProgressDialog();
break;
default:
if (eventBusMessage.object instanceof MyBookingsApi.ApiResponse)
parseMyBookingsSuccessResponse((MyBookingsApi.ApiResponse) eventBusMessage.object);
else if (eventBusMessage.object instanceof PastBookingsApi.ApiResponse) {
parsePastBookingsSuccessResponse((PastBookingsApi.ApiResponse) eventBusMessage.object);
} else if (eventBusMessage.object instanceof BaseApi.DefaultErrorResponse) {
parseErrorResponse((BaseApi.DefaultErrorResponse) eventBusMessage.object);
} else if (eventBusMessage.object instanceof BaseApi.Error500Response) {
//parseError500Response((BaseApi.Error500Response) eventBusMessage.object);
} else if (eventBusMessage.object instanceof MyBookingCancelApi.ApiResponse) {
parseCancelBookingSuccessResponse((MyBookingCancelApi.ApiResponse) eventBusMessage.object);
} else if (eventBusMessage.object instanceof MyBookingDeleteApi.ApiResponse) {
parseDeleteBookingSuccessResponse((MyBookingDeleteApi.ApiResponse) eventBusMessage.object);
}
break;
}
}
private void parseDeleteBookingSuccessResponse(MyBookingDeleteApi.ApiResponse apiResponse) {
showSnackBar(apiResponse.getMessage());
getMyPastBooking();
}
private void parseCancelBookingSuccessResponse(final MyBookingCancelApi.ApiResponse apiResponse) {
showSnackBar(apiResponse.getMessage());
getMyBooking();
/*final ProgressDialog pd = new ProgressDialog(MyBookingActivity.this);
pd.setMessage("Please wait..");
pd.show();
Handler mHandler = new Handler();
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
pd.dismiss();
startApiService(MyBookingDeleteApi.getServiceIntent(MyBookingActivity.this, getToken(), apiResponse.getData().getId()));
}
}, 800);*/
}
private void parsePastBookingsSuccessResponse(PastBookingsApi.ApiResponse apiResponse) {
List<PastBookingsApi.ApiResponse.Datum> datumList = apiResponse.getData();
if (datumList.size() > 0) {
Collections.sort(datumList, new Comparator<PastBookingsApi.ApiResponse.Datum>()
{
#Override
public int compare(PastBookingsApi.ApiResponse.Datum o1, PastBookingsApi.ApiResponse.Datum o2) {
return o1.getId() > o2.getId() ? -1 : (o1.getId() < o2.getId() ) ? 1 : 0;
}
});
mRVPastBookings.setAdapter(mBaseRecyclerAdapterMyPastBookings);
mBaseRecyclerAdapterMyPastBookings.setItems(datumList);
} else {
mRVPastBookings.setAdapter(new BaseEmptyRecyclerAdapter<EmptyViewHolderRefresh>(EmptyViewHolderRefresh.class, R.layout.layout_place_holderrefresh) {
#Override
protected void populateEmptyViewHolder(EmptyViewHolderRefresh viewHolder) {
viewHolder.mAppCompatImageView.setImageResource(R.drawable.no_booking_place_holder);
viewHolder.mCustomTextViewTitle.setText(R.string.no_bookings_available_title);
viewHolder.mCustomTextViewDescription.setText(R.string.no_bookings_available_description);
// viewHolder.mCustomButton.setText(R.string.try_again);
viewHolder.refreshText.setText(R.string.swipe);
viewHolder.mCustomButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// getMyPastBooking();
}
});
}
});
}
}
private void parseMyBookingsSuccessResponse(MyBookingsApi.ApiResponse apiResponse) {
// mCourtDataList = apiResponse.getData();
List<MyBookingsApi.ApiResponse.Datum> datumList = apiResponse.getData();
if (datumList.size() > 0) {
Collections.sort(datumList, new Comparator<MyBookingsApi.ApiResponse.Datum>()
{
#Override
public int compare(MyBookingsApi.ApiResponse.Datum o1, MyBookingsApi.ApiResponse.Datum o2) {
return o1.getId() > o2.getId() ? -1 : (o1.getId() < o2.getId() ) ? 1 : 0;
}
});
mRVOngoingBookings.setAdapter(mBaseRecyclerAdapterMyBookings);
mBaseRecyclerAdapterMyBookings.setItems(datumList);
} else {
mRVOngoingBookings.setAdapter(new BaseEmptyRecyclerAdapter<EmptyViewHolderRefresh>(EmptyViewHolderRefresh.class, R.layout.layout_place_holderrefresh) {
#Override
protected void populateEmptyViewHolder(EmptyViewHolderRefresh viewHolder) {
viewHolder.mAppCompatImageView.setImageResource(R.drawable.no_booking_place_holder);
viewHolder.mCustomTextViewTitle.setText(R.string.no_bookings_available_title);
viewHolder.mCustomTextViewDescription.setText(R.string.no_bookings_available_description);
//viewHolder.mCustomButton.setText(R.string.try_again);
viewHolder.refreshText.setText(R.string.swipe);
viewHolder.mCustomButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//getMyBooking();
}
});
}
});
}
}
private void parseError500Response(BaseApi.Error500Response error500Response) {
showAlertDialog(R.string.session_timeout_title, R.string.session_timeout_message, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
logout();
}
});
}
private void parseErrorResponse(BaseApi.DefaultErrorResponse defaultErrorResponse) {
showSnackBar(defaultErrorResponse.getMessage());
}
#Subscribe(threadMode = ThreadMode.MAIN)
public void noInternet(String message) {
mRVOngoingBookings.setAdapter(new BaseEmptyRecyclerAdapter<EmptyViewHolderRefresh>(EmptyViewHolderRefresh.class, R.layout.layout_place_holderrefresh) {
#Override
protected void populateEmptyViewHolder(EmptyViewHolderRefresh viewHolder) {
viewHolder.mAppCompatImageView.setImageResource(R.drawable.no_internet_placeholder);
viewHolder.mCustomTextViewTitle.setText(R.string.connection_problem_title);
viewHolder.mCustomTextViewDescription.setText(R.string.connection_problem_description);
viewHolder.refreshText.setText(R.string.swipe);
//viewHolder.mCustomButton.setText(R.string.try_again);
viewHolder.mCustomButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// getMyBooking();
}
});
}
});
mRVPastBookings.setAdapter(new BaseEmptyRecyclerAdapter<EmptyViewHolderRefresh>(EmptyViewHolderRefresh.class, R.layout.layout_place_holderrefresh) {
#Override
protected void populateEmptyViewHolder(EmptyViewHolderRefresh viewHolder) {
viewHolder.mAppCompatImageView.setImageResource(R.drawable.no_internet_placeholder);
viewHolder.mCustomTextViewTitle.setText(R.string.connection_problem_title);
viewHolder.mCustomTextViewDescription.setText(R.string.connection_problem_description);
viewHolder.refreshText.setText(R.string.swipe);
//viewHolder.mCustomButton.setText(R.string.try_again);
viewHolder.mCustomButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// getMyPastBooking();
}
});
}
});
}
}
and activity_my_booking layout is:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/layout_toolbar" />
<include layout="#layout/content_my_booking" />
</android.support.design.widget.CoordinatorLayout>
</android.support.v4.widget.SwipeRefreshLayout>
Set the first RecyclerView’s height to wrap_content and set setNestedScrollingEnabled to false
RecyclerView rv_ongoing_bookings= (RecyclerView) findViewById(R.id.rv_ongoing_bookings);
rv_ongoing_bookings.setNestedScrollingEnabled(false);
To achieve it my approach would be to customize my recyclerView adapter to act as a section header recycler view, something like this:
https://android-arsenal.com/details/1/4495
The following code will make recycler view expandable...
public class ExpandableRecyclerView extends RecyclerView
{
private boolean expanded = false;
public ExpandableRecyclerView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
public ExpandableRecyclerView(Context context)
{
super(context);
}
public ExpandableRecyclerView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public boolean isExpanded()
{
return expanded;
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
if (isExpanded())
{
int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
else
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public void setExpanded(boolean expanded)
{
this.expanded = expanded;
}
}
Usage... use it the way you use recycler view...
just set recyclerView.setExpanded(true);
You may directly use it inside scrollview...
So, it's not really an answer to your question, it's more like a suggestion to use RecyclerView as it should be depending on the screenshot which you included in your question.
You really don't need to create two RecyclerView's to achieve the layout which you need. As I understand you want to show some items and put a separator with text depending on something (Booking's date as I can see).
In RecyclerView.Adapter you have getItemViewType where you can return an int value depending on some variables.For example your getItemViewType should look something like this:
#Override
public int getItemViewType(int position) {
MyObject myObject = mItems.get(position);
// myObject.isSeparator() is a sample function which helps you identify it you should show construct a booking view or separator
if(myObject.isSeparator()){
// this variable is declared inside your Adapter ->
// private static final int VIEW_TYPE_SEPARATOR = 1;
return VIEW_TYPE_SEPARATOR;
}
// private static final int VIEW_TYPE_BOOKING = 0;
return VIEW_TYPE_BOOKING;
}
Depending on those values you need to create two ViewHolder's :
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if (VIEW_TYPE_SEPARATOR == viewType) {
new SeparatorViewHolder(/* Some params which you need here */);
}
return new BookingViewHolder(/* Some other params which you need here */);
}
And ->
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
if (VIEW_TYPE_SEPARATOR == getItemViewType(position)) {
// Populate SeparatorViewHolder
} else {
// Populate BookingViewHolder
}
}
And at the end you should populate your List with the objects you need to determine if the item is a Booking item for example or a Separator.
I hope you got the main idea.
Related
my problem is same as link given below
I have a ViewPager by same fragments RecyclerView just load items in one fragment of ViewPager
but at this post no one solve issue...
I have a recycler view items...I want when I click on recycler view item it takes me to viewpager fragment and shows that data of clicked item dynamically and on swiping viewpager it should move previous and next fragment accordingly...under fragment I want to show data of recyclerrview item using single fragment...
I have done this by using multiple fragment and using multiple instances by different name and different layout name and different id for its recyclerView and it works but i have a large number of fragments and it is not the solution for me ):
here is my viewpager code
public class AndroidViewPagerExample extends FragmentActivity {
ViewPager pager;
int positionring;
String rgtv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.mainuuuu);
Intent it = getIntent();
positionring = it.getIntExtra("POS", 0);
final int position = it.getIntExtra("POS", 0);
rgtv= it.getStringExtra("name");
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
pager.setPageTransformer(true, new RotateUpTransformer());
pager.setCurrentItem(position);
pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
Boolean first = true;
Boolean userScrollChange=false;
public void onPageScrollStateChanged(int state) {
System.out.println("onPageScrollStateChanged");
System.out.println("Current position=="+position);
int curreentpos=position;
int newpos=curreentpos+1;
int previousState=curreentpos-1;
if (previousState == pager.SCROLL_STATE_DRAGGING
&& state == pager.SCROLL_STATE_SETTLING)
userScrollChange = true;
else if (previousState == pager.SCROLL_STATE_SETTLING
&& state == pager.SCROLL_STATE_IDLE)
userScrollChange = false;
previousState = state;
}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
System.out.println("onPageScrolled");
}
public void onPageSelected(int position) {
// Check if this is the page you want.
System.out.println("onPageSelected");
Apples.newInstance(rgtv);
}
});
}
private class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public android.support.v4.app.Fragment getItem(int position) {
return Apples.newInstance(rgtv);
}
#Override
public int getCount() {
return ringtonelist.size();
}
}
#Override
public void onBackPressed() {
// if (pager.getCurrentItem() != 36) {
// pager.setCurrentItem(36);
// } else {
Vp_Ringtoneplaybtn.Playstop();
super.onBackPressed();
// }
}
}
code given below is adapter code
public class RingToneAdapter extends RecyclerView.Adapter<RingToneAdapter.RingToneViewHolder> {
public int mSelectedItem = -1;
static MediaPlayer mp;
View view;
static Context rcntx;
int oldpossssssss;
List<RingTone_Items> ringtonelist;
private TextView hello, close;
ImageView prev, next;
private ImageView iconplay;
private InterstitialAd mInterstitialAd;
Dialog MyDialog;
static final int[] resID = {R.raw.a48, R.raw.funny_hen, R.raw.funny_roster_1, R.raw.funny_roster_2, R.raw.rooster_1, R.raw.rooster_2,R.raw.rooster_3,R.raw.funny_cock,R.raw.a12,R.raw.a45,R.raw.a44,R.raw.a43,R.raw.a31, R.raw.a10,R.raw.chicken_1,R.raw.chick_2,R.raw.chick_3,R.raw.chick_4,R.raw.chick_5,R.raw.chick_6};
public RingToneAdapter(Context rcntx, List<RingTone_Items> ringtonelist) {
this.rcntx = rcntx;
this.ringtonelist = ringtonelist;
}
#NonNull
#Override
public RingToneViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
view = LayoutInflater.from(rcntx).inflate(R.layout.ringtone_values, viewGroup, false);
RingToneViewHolder ringToneViewHolder = new RingToneViewHolder(view);
return ringToneViewHolder;
}
#Override
public void onBindViewHolder(#NonNull final RingToneViewHolder ringToneViewHolder, final int i) {
final RingTone_Items ringTone_items = ringtonelist.get(i);
ringToneViewHolder.rtv.setText(ringTone_items.getRintonetv());
if (mSelectedItem == i) { // mSelectedItem = -1 and at 1st time
// there is no position selected...so the condition goes false...go
// to else condtion
ringToneViewHolder.iconplay.setImageResource(R.drawable.ic_pause_black_24dp);
} else {
ringToneViewHolder.iconplay.setImageResource(R.drawable.ic_play_arrow_black_24dp); // all icons will show play icon
}
ringToneViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// MyCustomAlertDialog(i);
if (mp != null && mp.isPlaying()) {
mp.stop();
mp.reset();
mp = null;
ringToneViewHolder.iconplay.setImageResource(R.drawable.ic_play_arrow_black_24dp);
}
//Intent it = new Intent(rcntx, ViewPager_Data.class);
Intent it = new Intent(rcntx, AndroidViewPagerExample.class);
it.putExtra("POS",i);
it.putExtra("name",ringTone_items.getRintonetv());
// mInterstitialAd = new InterstitialAd(rcntx);
// mInterstitialAd.setAdUnitId(rcntx.getResources().getString(R.string.ad_interstitial));
// AdRequest adRequest = new AdRequest.Builder().build();
// mInterstitialAd.loadAd(adRequest);
// mInterstitialAd.setAdListener(new AdListener() {
// public void onAdLoaded() {
// if (mInterstitialAd.isLoaded()) {
// mInterstitialAd.show();
// }
// }
// });
rcntx.startActivity(it);
}
});
ringToneViewHolder.iconplay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mSelectedItem == i) {
mSelectedItem = -1;
oldpossssssss = i;
} else {
mSelectedItem = i;
}
notifyDataSetChanged(); //update the position of row...notifyDataSetChanged is bindview method
if (mp != null && mp.isPlaying()) {
mp.stop();
//mp.deselectTrack(resID[i]);
mp.reset();
mp.release();
mp = null;
if (oldpossssssss == i) {
} else {
mp = new MediaPlayer();
mp = MediaPlayer.create(rcntx, resID[i]);
mp.start();
}
} else {
// MyCustomAlertDialog(i);
mp = new MediaPlayer();
mp = MediaPlayer.create(rcntx, resID[i]);
mp.start();
}
}
});
}
#Override
public int getItemCount() {
return ringtonelist.size();
}
class RingToneViewHolder extends RecyclerView.ViewHolder {
private TextView rtv, hello, close;
private ImageView iconplay;
public RingToneViewHolder(#NonNull View itemView) {
super(itemView);
rtv = itemView.findViewById(R.id.ringtitle);
iconplay = itemView.findViewById(R.id.playicon);
}
}
public void InterstitialAdmob() {
mInterstitialAd = new InterstitialAd(rcntx);
mInterstitialAd.setAdUnitId(rcntx.getResources().getString(R.string.ad_interstitial));
mInterstitialAd.setAdListener(new AdListener() {
#Override
public void onAdClosed() {
requestNewInterstitial();
}
});
requestNewInterstitial();
}
protected void requestNewInterstitial() {
AdRequest adRequest = new AdRequest.Builder().build();
mInterstitialAd.loadAd(adRequest);
}
}
here is main activity code
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
RingToneAdapter adapter;
public static ArrayList<RingTone_Items> ringtonelist;
//final int[] resID = {R.raw.alert};
public static int posss;
private String[] fruitlist = new String[]{"Funny hen 1", "Funny hen 2", "Funny roaster 1", "Funny roaster 2","Funny roaster 3", "Funny roaster 4", "funny roaster 5","Funny cock", "Funny hen alarm","Abstracts", "Wake up", "Funny tone","Get up","Alarm","Hen sound 1","Hen sound 2","Hen sound 3","Hen sound 4","Hen sound 5","Hen sound 6"};
private boolean isFABOpen;
FloatingActionButton fab,fab1, fab3;
FrameLayout fab2;
AdView mAdView;
RelativeLayout layout_no, layoutrateus, layout_yes, adlayout, adlayout1;
private static final int PERMISSION_REQUEST_CODE = 1;
private String fNmae = String.valueOf(R.raw.alarm);
private String fPAth = "android.resource://packagename/raw/alarm";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recycler);
// Here, thisActivity is the current activity
if (Build.VERSION.SDK_INT >= 23) {
if (checkPermission()) {
if (Settings.System.canWrite(MainActivity.this)) {
//setRingtone();
} else {
Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS)
.setData(Uri.parse("package:" + getPackageName()))
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
Log.e("value", "Permission already Granted, Now you can save image.");
} else {
requestPermission();
}
} else {
// setRingtone();
Log.e("value", "Not required for requesting runtime permission");
}
mAdView = (AdView) findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
mAdView.loadAd(adRequest);
//recyclerView.setBackgroundColor(getResources().getColor(R.color.colorAccent));
recyclerView.setBackground(getResources().getDrawable(R.drawable.bg));
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
// RecyclerView.LayoutManager mLayoutManager =
// new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.HORIZONTAL, false);
ringtonelist = getRingTone_Items();
adapter = new RingToneAdapter(this, ringtonelist);
recyclerView.setAdapter(adapter);
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), recyclerView, new RecyclerTouchListener.ClickListener() {
#Override
public void onClick(View view, int position) {
RingTone_Items itemrg = ringtonelist.get(position);
posss=position;
}
#Override
public void onLongClick(View view, int position) {
}
}));
}
protected boolean checkPermission() {
int result = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (result == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
protected void requestPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(MainActivity.this, "Write External Storage permission allows us to do store images. Please allow this permission in App Settings.", Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.e("value", "Permission Granted, Now you can save image .");
if (Build.VERSION.SDK_INT >= 23) {
if (Settings.System.canWrite(MainActivity.this)) {
// setRingtone();
} else {
Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS)
.setData(Uri.parse("package:" + getPackageName()))
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
} else {
Log.e("value", "Permission Denied, You cannot save image.");
}
break;
}
}
private ArrayList<RingTone_Items> getRingTone_Items(){
ArrayList<RingTone_Items> list = new ArrayList<>();
for(int i = 0; i < 20; i++){
RingTone_Items model = new RingTone_Items();
model.setRintonetv(fruitlist[i]);
list.add(model);
}
return list;
}
public void onBackPressed(){
if (mp != null && mp.isPlaying()) {
mp.pause();
mp.stop();
mp.release();
mp = null;
}
onexit();
}
public void onexit() {
android.view.LayoutInflater layout1 = android.view.LayoutInflater.from(this);
View view1 = layout1.inflate(R.layout.backpress, null);
final RelativeLayout relativeLayout=(RelativeLayout) view1.findViewById(R.id.layout_top);
final AlertDialog.Builder gotoBuilder1 = new AlertDialog.Builder(this);
gotoBuilder1.setView(view1);
final AlertDialog gotoDialog1 = gotoBuilder1.create();
layout_no = view1.findViewById(R.id.layoutno);
layoutrateus = view1.findViewById(R.id.layoutrateus);
layout_yes = view1.findViewById(R.id.layout_yes);
layout_no.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
gotoDialog1.dismiss();
}
});
layoutrateus.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
Intent mintent = new Intent(Intent.ACTION_VIEW);
mintent.setData(android.net.Uri.parse("market://details?id="
+ getPackageName()));
startActivity(mintent);
} catch (Exception e1) {
try {
android.net.Uri uriUrl = android.net.Uri
.parse("https://market.android.com/details?id="
+ getPackageName());
Intent launchBrowser = new Intent(Intent.ACTION_VIEW,
uriUrl);
startActivity(launchBrowser);
} catch (Exception e2) {
android.widget.Toast.makeText(getApplicationContext(),
"No Application Found to open link",
android.widget.Toast.LENGTH_SHORT).show();
}
}
gotoDialog1.dismiss();
}
});
layout_yes.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
} catch (Exception e) {
}
gotoDialog1.dismiss();
finish();
}
});
gotoDialog1.getWindow().setLayout(android.view.ViewGroup.LayoutParams.MATCH_PARENT,
android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
gotoDialog1.show();
}
public void onDestroy() {
super.onDestroy();
}
}
this is my fragment
public class Apples extends BaseFragment{
ImageView vpbtn;
MediaPlayer mp;
ImageView tvshare;
static String s;
static TextView rgtname;
int position = 0;
private ShareActionProvider mShareActionProvider;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.apple, container, false);
vpbtn = (ImageView) v.findViewById(R.id.iconplaypause);
mAdView = (AdView) v.findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
mAdView.loadAd(adRequest);
rgtname=v.findViewById(R.id.rgtname);
rgtname.setText(s);
tvshare=v.findViewById(R.id.tvshare);
fab = v.findViewById(R.id.fab);
fab1 = v.findViewById(R.id.frm1);
fab2 = v.findViewById(R.id.frm2);
fab3 = v.findViewById(R.id.frm3);
// Vp_Ringtoneplaybtn.Setrintones(fab,fab1,fab2,fab3);
// tvshare.setOnClickListener(new View.OnClickListener() {
// #Override
// public void onClick(View v) {
// Vp_Ringtoneplaybtn.shareapp();
// }
// });
Vp_Ringtoneplaybtn.shareapp(tvshare);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(!isFABOpen){
showFABMenu();
}else{
closeFABMenu();
}
}
});
Vp_Ringtoneplaybtn.Setrintones(fab1,fab2,fab3,position);
vpbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Vp_Ringtoneplaybtn.PlaySound( vpbtn, position);
}
});
return v;
}
public static Apples newInstance(String rgtvv) {
s=rgtvv;
Apples f16 = new Apples();
return f16;
}
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (this.isVisible()) {
// If we are becoming invisible, then...
if (!isVisibleToUser) {
Vp_Ringtoneplaybtn.Playstop();
vpbtn.setImageResource(R.drawable.ic_play_arrow_black_24dp);
} else {
// do what you like
}
}
}
#Override
public void onPause() {
super.onPause();
}
}
Basically i followed the accepted answer of this with few changes in my Activity and it worked perfect. My problem is that I wrote the exact same codes for my Fragment. when I open my app, it doesn't show anything. Before I changed my code in my fragment from a custom Adapter to the FirebaseRecyclerAdapter, everything worked fine.
This is my Fragment class
public class HomeFragment extends BaseFragment {
public Button buttonsrch, openFreezer, openRef, openPantry, scrollToFreezer, scrollToRef, scrollToPantry;
public NestedScrollView scrollView;
public RelativeLayout mFreezerLayout,mRefrigeratorLayout, mPantryLayout;
public FloatingActionButton mAddItems;
public DatabaseReference mDatabaseFreezer;
public RecyclerView mFreezerRecyclerView;
public ArrayList<Event> mDataSet;
private FirebaseRecyclerAdapter<Event, ProductHolder> firebaseRecyclerAdapter;
#Override
public int getLayoutResId() {
return R.layout.fragment_home;
}
#Override
public View inOnCreateView(View root, #Nullable ViewGroup container, Bundle savedInstancesState) {
View view = mRoot;
buttonsrch = view.findViewById(R.id.searchButton);
openPantry = view.findViewById(R.id.ShowMorePantry);
openRef = view.findViewById(R.id.ShowMoreRefrigerator);
openFreezer = view.findViewById(R.id.ShowMoreFreezer);
scrollToFreezer = view.findViewById(R.id.bringToFreezer);
scrollToPantry = view.findViewById(R.id.bringToPantry);
scrollToRef = view.findViewById(R.id.bringToRefrigerator);
scrollView = view.findViewById(R.id.scrollViewHomeFragment);
mFreezerLayout = view.findViewById(R.id.FreezerLayout);
mPantryLayout =view.findViewById(R.id.PantryRelativeLayout);
mRefrigeratorLayout = view.findViewById(R.id.RefrigeratorRelativeLayout);
mAddItems = view.findViewById(R.id.addItems_Inventory);
mAddItems.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(getActivity(), AddInventoryActivity.class));
}
});
buttonsrch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(getActivity(), Search_Activity.class);
getActivity().startActivity(i);
}
});
openPantry.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent h = new Intent(getActivity(), PantryActivity.class);
getActivity().startActivity(h);
}
});
openRef.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent g = new Intent(getActivity(), RefActivity.class);
getActivity().startActivity(g);
}
});
openFreezer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent s = new Intent(getActivity(), FreezerActivity.class);
getActivity().startActivity(s);
}
});
scrollToFreezer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FocusToFreezer();
}
});
scrollToRef.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FocusToRef();
}
});
scrollToPantry.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FocusToPantry();
}
});
mDataSet = new ArrayList<>();
mFreezerRecyclerView = view.findViewById(R.id.FreezerRecyclerView);
mFreezerRecyclerView.setHasFixedSize(true);
mFreezerRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mDatabaseFreezer = FirebaseDatabase.getInstance().getReference().child("FreezerItems");
Query query = mDatabaseFreezer;
FirebaseRecyclerOptions<Event> firebaseRecyclerOptions = new FirebaseRecyclerOptions.Builder<Event>()
.setQuery(query, Event.class).build();
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Event, ProductHolder>(firebaseRecyclerOptions) {
#Override
protected void onBindViewHolder(ProductHolder holder, int position, Event model) {
model = mDataSet.get(position);
holder.mItemName.setText(model.getName());
holder.mItemDate.setText(model.getDate());
final Event finalModel = model;
holder.mDeleteBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mDatabaseFreezer.child(finalModel.get_id()).removeValue();
}
});
}
#Override
public ProductHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recycler_view_row_inventory,parent,false);
return new ProductHolder(view);
}
};
mDatabaseFreezer.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
HashMap<String, String> value = (HashMap<String,String>) dataSnapshot.getValue();
if (value != null) {
String name = value.get("Name");
String date = value.get("Date");
String key = value.get("Key");
mDataSet.add(new Event(name,date,null, key));
Collections.sort(mDataSet, new Comparator<Event>() {
#Override
public int compare(Event event, Event t1) {
if (event.getDate() == null || t1.getDate() == null)
return 0;
return event.getDate().compareTo(t1.getDate());
}
});
}
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
mFreezerRecyclerView.setAdapter(firebaseRecyclerAdapter);
return root;
}
private class ProductHolder extends RecyclerView.ViewHolder{
private TextView mItemName, mItemDate;
private Button mDeleteBtn;
public ProductHolder(View itemView) {
super(itemView);
mItemName = itemView.findViewById(R.id.ItemNameTxtView);
mItemDate = itemView.findViewById(R.id.BestBeoforeTxtView);
mDeleteBtn = itemView.findViewById(R.id.deleteItem);
}
}
#Override
public void onStart() {
super.onStart();
firebaseRecyclerAdapter.startListening();
}
#Override
public void onStop() {
super.onStop();
if (firebaseRecyclerAdapter != null){
firebaseRecyclerAdapter.startListening();
}
}
private void FocusToFreezer(){
scrollView.post(new Runnable() {
#Override
public void run() {
scrollView.smoothScrollTo(0, mFreezerLayout.getTop());
}
});
}
private void FocusToRef(){
scrollView.post(new Runnable() {
#Override
public void run() {
scrollView.smoothScrollTo(0, mRefrigeratorLayout.getTop());
}
});
}
private void FocusToPantry(){
scrollView.post(new Runnable() {
#Override
public void run() {
scrollView.smoothScrollTo(0, mPantryLayout.getTop());
}
});
}
}
The only difference I could find is OnStart() and onStop() in activity are protected while on fragments are public
EDIT I found another page with the same problem and apparently FirebaseRecyclerAdapter doesn't work well with Fragments
I finally found an answer
simply remove mFreezerRecyclerView.setHasFixedSize(true);
I am using quickblox for my android application. I am able to register, login user, even add custom objects and retrieve them from the quick-blox server, but in chatting listing screen my count is coming wrong.
I am getting issue with unread count
Here is my code flow:-
public class ConversationFragment extends Fragment implements Observer, DialogsManager.ManagingDialogsCallbacks {
ConversationViewModel conversationViewModel;
FragmentConversationBinding binding;
QBChatDialogMessageListener allDialogsMessagesListener;
SystemMessagesListener systemMessagesListener;
QBSystemMessagesManager systemMessagesManager;
QBIncomingMessagesManager incomingMessagesManager;
private DialogsManager dialogsManager;
public ConversationFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_conversation, container, false);
getActivity().getWindow().setBackgroundDrawableResource(R.drawable.bg_img);
View view = binding.getRoot();
systemMessagesListener = new SystemMessagesListener();
dialogsManager = new DialogsManager();
return view;
}
private void setUpModel() {
Bundle mBundle = getArguments();
if (mBundle != null) {
conversationViewModel = new ConversationViewModel(getActivity(), binding, getArguments().getString("DialogIdData"));
} else {
conversationViewModel = new ConversationViewModel(getActivity(), binding, "");
}
binding.setConversationViewModel(conversationViewModel);
setUpObserver(conversationViewModel);
}
private void setUpObserver(ConversationViewModel observer) {
observer.addObserver(this);
}
#Override
public void update(Observable o, Object arg) {
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onResume() {
super.onResume();
setUpModel();
}
#Override
public void onPause() {
super.onPause();
unregisterQbChatListeners();
}
public void unregisterQbChatListeners() {
if (incomingMessagesManager != null) {
incomingMessagesManager.removeDialogMessageListrener(allDialogsMessagesListener);
}
if (systemMessagesManager != null) {
systemMessagesManager.removeSystemMessageListener(systemMessagesListener);
}
dialogsManager.removeManagingDialogsCallbackListener(this);
}
#Override
public void onDialogCreated(QBChatDialog chatDialog) {
}
#Override
public void onDialogUpdated(String chatDialog) {
}
#Override
public void onNewDialogLoaded(QBChatDialog chatDialog) {
}
private class SystemMessagesListener implements QBSystemMessageListener {
#Override
public void processMessage(final QBChatMessage qbChatMessage) {
dialogsManager.onSystemMessageReceived(qbChatMessage);
}
#Override
public void processError(QBChatException e, QBChatMessage qbChatMessage) {
}
}
private BroadcastReceiver mNotificationReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
}
};
}
Here is my Fragment viewModel code :-
public class ConversationViewModel extends Observable implements DialogsManager.ManagingDialogsCallbacks {
private static final int REQUEST_DIALOG_ID_FOR_UPDATE = 165;
public Context mContext;
FragmentConversationBinding binding;
private ActionMode currentActionMode;
public QBRequestGetBuilder requestBuilder;
private int skipRecords = 0;
private DialogsAdapter dialogsAdapter;
private QBChatDialogMessageListener allDialogsMessagesListener;
private SystemMessagesListener systemMessagesListener;
private QBSystemMessagesManager systemMessagesManager;
private QBIncomingMessagesManager incomingMessagesManager;
private DialogsManager dialogsManager;
private QBUser currentUser;
private String id;
public ConversationViewModel(Context mContext, FragmentConversationBinding binding, String Dialogid) {
this.mContext = mContext;
this.binding = binding;
this.id = Dialogid;
initUI();
}
public void initUI() {
allDialogsMessagesListener = new AllDialogsMessageListener();
systemMessagesListener = new SystemMessagesListener();
dialogsManager = new DialogsManager();
currentUser = ChatHelper.getCurrentUser();
initList();
registerQbChatListeners();
if (QbDialogHolder.getInstance().getDialogs().size() > 0) {
loadDialogsFromQb(true, true);
} else {
loadDialogsFromQb(false, true);
}
if (!id.isEmpty()) {
loadUpdatedDialog(id);
id = "";
} else {
updateDialogsList();
}
}
public void initList() {
dialogsAdapter = new DialogsAdapter(mContext, new ArrayList<>(QbDialogHolder.getInstance().getDialogs().values()));
binding.listDialogsChats.setAdapter(dialogsAdapter);
binding.listDialogsChats.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
QBChatDialog selectedDialog = (QBChatDialog) parent.getItemAtPosition(position);
if (currentActionMode == null) {
ChatActivity.startForResult(((Activity) mContext), REQUEST_DIALOG_ID_FOR_UPDATE, selectedDialog);
} else {
dialogsAdapter.toggleSelection(selectedDialog);
}
}
});
binding.listDialogsChats.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
QBChatDialog selectedDialog = (QBChatDialog) parent.getItemAtPosition(position);
dialogsAdapter.selectItem(selectedDialog);
return true;
}
});
requestBuilder = new QBRequestGetBuilder();
binding.swipyRefreshLayout.setOnRefreshListener(new SwipyRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh(SwipyRefreshLayoutDirection direction) {
requestBuilder.setSkip(skipRecords += ChatHelper.DIALOG_ITEMS_PER_PAGE);
loadDialogsFromQb(true, false);
}
});
}
private void loadUpdatedDialog(String dialogId) {
ChatHelper.getInstance().getDialogById(dialogId, new QbEntityCallbackImpl<QBChatDialog>() {
#Override
public void onSuccess(QBChatDialog result, Bundle bundle) {
QbDialogHolder.getInstance().addDialog(result);
updateDialogsAdapter();
}
#Override
public void onError(QBResponseException e) {
}
});
}
public void updateDialogsList() {
requestBuilder.setSkip(skipRecords = 0);
loadDialogsFromQb(true, true);
}
#Override
public void onDialogCreated(QBChatDialog chatDialog) {
updateDialogsAdapter();
}
#Override
public void onDialogUpdated(String chatDialog) {
updateDialogsAdapter();
}
#Override
public void onNewDialogLoaded(QBChatDialog chatDialog) {
updateDialogsAdapter();
}
private void registerQbChatListeners() {
incomingMessagesManager = QBChatService.getInstance().getIncomingMessagesManager();
systemMessagesManager = QBChatService.getInstance().getSystemMessagesManager();
if (incomingMessagesManager != null) {
incomingMessagesManager.addDialogMessageListener(allDialogsMessagesListener != null
? allDialogsMessagesListener : new AllDialogsMessageListener());
}
if (systemMessagesManager != null) {
systemMessagesManager.addSystemMessageListener(systemMessagesListener != null
? systemMessagesListener : new SystemMessagesListener());
}
dialogsManager.addManagingDialogsCallbackListener(this);
}
private class SystemMessagesListener implements QBSystemMessageListener {
#Override
public void processMessage(final QBChatMessage qbChatMessage) {
dialogsManager.onSystemMessageReceived(qbChatMessage);
}
#Override
public void processError(QBChatException e, QBChatMessage qbChatMessage) {
}
}
private class AllDialogsMessageListener extends QbChatDialogMessageListenerImp {
#Override
public void processMessage(final String dialogId, final QBChatMessage qbChatMessage, Integer senderId) {
if (!senderId.equals(ChatHelper.getCurrentUser().getId())) {
dialogsManager.onGlobalMessageReceived(dialogId, qbChatMessage);
}
}
}
public void updateDialogsAdapter() {
dialogsAdapter.updateList(new ArrayList<>(QbDialogHolder.getInstance().getDialogs().values()));
}
public void loadDialogsFromQb(final boolean silentUpdate, final boolean clearDialogHolder) {
if (!silentUpdate) {
binding.progressDialogs.setVisibility(View.VISIBLE);
}
ChatHelper.getInstance().getDialogs(requestBuilder, new QBEntityCallback<ArrayList<QBChatDialog>>() {
#Override
public void onSuccess(ArrayList<QBChatDialog> dialogs, Bundle bundle) {
binding.progressDialogs.setVisibility(View.GONE);
binding.swipyRefreshLayout.setRefreshing(false);
if (clearDialogHolder) {
QbDialogHolder.getInstance().clear();
}
QbDialogHolder.getInstance().addDialogs(dialogs);
updateDialogsAdapter();
}
#Override
public void onError(QBResponseException e) {
binding.progressDialogs.setVisibility(View.GONE);
binding.swipyRefreshLayout.setRefreshing(false);
Toast.makeText(mContext, e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
Here is my Chat Activity:-
public class ChatActivity extends BindingActivity<ActivityChatBinding> implements OnImagePickedListener {
ChatViewModel chatViewModel;
public static final int REQUEST_CODE_ATTACHMENT = 721;
public static final String EXTRA_DIALOG_ID = "dialogId";
#Override
protected int getLayoutId() {
return R.layout.activity_chat;
}
public static void startForResult(Activity activity, int code, QBChatDialog dialogId) {
Intent intent = new Intent(activity, ChatActivity.class);
intent.putExtra(ChatActivity.EXTRA_DIALOG_ID, dialogId);
activity.startActivityForResult(intent, code);
}
#Override
public void setInitBinding() {
getWindow().setBackgroundDrawableResource(R.drawable.bg_img);
chatViewModel = new ChatViewModel(this, binding);
binding.setChatViewModel(chatViewModel);
}
#Override
protected void setUpObserver() {
chatViewModel.addObserver(this);
}
#Override
public void update(Observable o, Object arg) {
}
#Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
#Override
public void onBackPressed() {
binding.getChatViewModel().releaseChat();
binding.getChatViewModel().sendDialogId();
super.onBackPressed();
}
#Override
public void onImagePicked(int requestCode, File file) {
switch (requestCode) {
case REQUEST_CODE_ATTACHMENT:
binding.getChatViewModel().attachmentPreviewAdapter.add(file);
break;
}
}
#Override
public void onImagePickError(int requestCode, Exception e) {
Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show();
}
#Override
public void onImagePickClosed(int requestCode) {
}
}
Chat Activity View Model :-
public class ChatViewModel extends Observable {
public Context mContext;
ActivityChatBinding binding;
public static final String TAG = ChatActivity.class.getSimpleName();
public static final int REQUEST_CODE_ATTACHMENT = 721;
public static final String PROPERTY_SAVE_TO_HISTORY = "save_to_history";
public static final String EXTRA_DIALOG_ID = "dialogId";
public ChatAdapter chatAdapter;
public AttachmentPreviewAdapter attachmentPreviewAdapter;
public QBChatDialog qbChatDialog;
public ArrayList<QBChatMessage> unShownMessages;
public int skipPagination = 0;
public ChatMessageListener chatMessageListener;
QBPrivacyList qbPrivacyList;
public static boolean mBlock;
public static int userId, recipientId;
public QBPrivacyListsManager privacyListsManager;
public ObservableField<String> chatMessage = new ObservableField<>("");
public ChatViewModel(Context mContext, ActivityChatBinding binding) {
this.mContext = mContext;
this.binding = binding;
Log.v(TAG, "onCreate ChaActivity on Thread ID = " + Thread.currentThread().getId());
qbChatDialog = (QBChatDialog) ((Activity) mContext).getIntent().getSerializableExtra(EXTRA_DIALOG_ID);
Log.v(TAG, "deserialized dialog = " + qbChatDialog);
qbChatDialog.initForChat(QBChatService.getInstance());
chatMessageListener = new ChatMessageListener();
qbPrivacyList = new QBPrivacyList();
privacyListsManager = QBChatService.getInstance().getPrivacyListsManager();
qbChatDialog.addMessageListener(chatMessageListener);
initViews();
initChat();
}
public void initViews() {
try {
recipientId = qbChatDialog.getRecipientId();
userId = qbChatDialog.getUserId();
getPrivacyList();
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
}
attachmentPreviewAdapter = new AttachmentPreviewAdapter(mContext,
new AttachmentPreviewAdapter.OnAttachmentCountChangedListener() {
#Override
public void onAttachmentCountChanged(int count) {
binding.attachmentContainer.setVisibility(count == 0 ? View.GONE : View.VISIBLE);
}
},
new AttachmentPreviewAdapter.OnAttachmentUploadErrorListener() {
#Override
public void onAttachmentUploadError(QBResponseException e) {
Toast.makeText(mContext, e.toString(), Toast.LENGTH_SHORT).show();
}
});
binding.attachmentAdapter.setAdapter(attachmentPreviewAdapter);
}
public void onAttachmentsClick(View view) {
new ImagePickHelper().pickAnImage(((FragmentActivity) mContext), REQUEST_CODE_ATTACHMENT);
}
private void initChat() {
switch (qbChatDialog.getType()) {
case PRIVATE:
loadDialogUsers();
break;
default:
Toaster.shortToast(String.format("%s %s", getString(R.string.chat_unsupported_type), qbChatDialog.getType().name()));
((Activity) mContext).finish();
break;
}
}
public void loadDialogUsers() {
ChatHelper.getInstance().getUsersFromDialog(qbChatDialog, new QBEntityCallback<ArrayList<QBUser>>() {
#Override
public void onSuccess(ArrayList<QBUser> users, Bundle bundle) {
String chatName = QbDialogUtils.getDialogName(qbChatDialog);
binding.dialogName.setText(chatName);
loadChatHistory();
}
#Override
public void onError(QBResponseException e) {
Toast.makeText(mContext, e.toString(), Toast.LENGTH_SHORT).show();
}
});
}
public void loadChatHistory() {
ChatHelper.getInstance().loadChatHistory(qbChatDialog, skipPagination, new QBEntityCallback<ArrayList<QBChatMessage>>() {
#Override
public void onSuccess(ArrayList<QBChatMessage> messages, Bundle args) {
Collections.reverse(messages);
if (chatAdapter == null) {
chatAdapter = new ChatAdapter(mContext, qbChatDialog, messages);
chatAdapter.setPaginationHistoryListener(new PaginationHistoryListener() {
#Override
public void downloadMore() {
loadChatHistory();
}
});
chatAdapter.setOnItemInfoExpandedListener(new ChatAdapter.OnItemInfoExpandedListener() {
#Override
public void onItemInfoExpanded(final int position) {
if (isLastItem(position)) {
((Activity) mContext).runOnUiThread(new Runnable() {
#Override
public void run() {
binding.listChat.setSelection(position);
}
});
} else {
binding.listChat.smoothScrollToPosition(position);
}
}
private boolean isLastItem(int position) {
return position == chatAdapter.getCount() - 1;
}
});
if (unShownMessages != null && !unShownMessages.isEmpty()) {
List<QBChatMessage> chatList = chatAdapter.getList();
for (QBChatMessage message : unShownMessages) {
if (!chatList.contains(message)) {
chatAdapter.add(message);
}
}
}
binding.listChat.setAdapter(chatAdapter);
binding.listChat.setAreHeadersSticky(false);
binding.listChat.setDivider(null);
} else {
chatAdapter.addList(messages);
binding.listChat.setSelection(messages.size());
}
binding.progressBar.setVisibility(View.GONE);
}
#Override
public void onError(QBResponseException e) {
binding.progressBar.setVisibility(View.GONE);
skipPagination -= ChatHelper.CHAT_HISTORY_ITEMS_PER_PAGE;
Toast.makeText(mContext, e.toString(), Toast.LENGTH_SHORT).show();
}
});
skipPagination += ChatHelper.CHAT_HISTORY_ITEMS_PER_PAGE;
QBRestChatService.markMessagesAsRead(qbChatDialog.getDialogId(), null);
}
public class ChatMessageListener extends QbChatDialogMessageListenerImp {
#Override
public void processMessage(String s, QBChatMessage qbChatMessage, Integer integer) {
showMessage(qbChatMessage);
}
}
public void showMessage(QBChatMessage message) {
if (chatAdapter != null) {
chatAdapter.add(message);
scrollMessageListDown();
} else {
if (unShownMessages == null) {
unShownMessages = new ArrayList<>();
}
unShownMessages.add(message);
}
}
public void scrollMessageListDown() {
binding.listChat.setSelection(binding.listChat.getCount() - 1);
}
public void onSendChatClick(View view) {
int totalAttachmentsCount = attachmentPreviewAdapter.getCount();
Collection<QBAttachment> uploadedAttachments = attachmentPreviewAdapter.getUploadedAttachments();
if (!uploadedAttachments.isEmpty()) {
if (uploadedAttachments.size() == totalAttachmentsCount) {
for (QBAttachment attachment : uploadedAttachments) {
sendChatMessage(null, attachment);
}
} else {
Toaster.shortToast(R.string.chat_wait_for_attachments_to_upload);
}
}
String text = binding.getChatViewModel().chatMessage.get().trim();
if (!TextUtils.isEmpty(text)) {
sendChatMessage(text, null);
}
}
public void sendChatMessage(String text, QBAttachment attachment) {
QBChatMessage chatMessage = new QBChatMessage();
if (attachment != null) {
chatMessage.addAttachment(attachment);
} else {
chatMessage.setBody(text);
}
chatMessage.setProperty(PROPERTY_SAVE_TO_HISTORY, "1");
chatMessage.setDateSent(System.currentTimeMillis() / 1000);
chatMessage.setMarkable(true);
if (!QBDialogType.PRIVATE.equals(qbChatDialog.getType()) && !qbChatDialog.isJoined()) {
Toaster.shortToast("You're still joining a group chat, please wait a bit");
return;
}
try {
qbChatDialog.sendMessage(chatMessage);
if (QBDialogType.PRIVATE.equals(qbChatDialog.getType())) {
showMessage(chatMessage);
}
if (attachment != null) {
attachmentPreviewAdapter.remove(attachment);
} else {
binding.getChatViewModel().chatMessage.set("");
}
} catch (SmackException.NotConnectedException e) {
Log.w(TAG, e);
Toaster.shortToast("Can't send a message, You are not connected to chat");
}
}
public void leaveGroupDialog() {
try {
ChatHelper.getInstance().leaveChatDialog(qbChatDialog);
} catch (XMPPException | SmackException.NotConnectedException e) {
Log.w(TAG, e);
}
}
public void releaseChat() {
qbChatDialog.removeMessageListrener(chatMessageListener);
if (!QBDialogType.PRIVATE.equals(qbChatDialog.getType())) {
leaveGroupDialog();
}
}
public void sendDialogId() {
Intent result = new Intent();
result.putExtra(EXTRA_DIALOG_ID, qbChatDialog.getDialogId());
((Activity) mContext).setResult(RESULT_OK, result);
}
public void finishActivity(View view) {
((Activity) mContext).finish();
}
public void clickButtonBlock(View view) {
AppUtils.dialog(mContext);
if (mBlock) {
onClickUnblock();
} else {
onClickBlock();
}
}
public void getPrivacyList() throws SmackException.NotConnectedException, XMPPException.XMPPErrorException, SmackException.NoResponseException {
QBPrivacyListsManager privacyListsManager = QBChatService.getInstance().getPrivacyListsManager();
QBPrivacyList privacyList = privacyListsManager.getPrivacyList("public");
List<QBPrivacyListItem> items = privacyList.getItems();
int i;
for (i = 0; i < privacyList.getItems().size(); i++) {
QBPrivacyListItem item = items.get(i);
String valueForType = item.getValueForType();
String[] splitvalueType = valueForType.split("-");
String blockId = splitvalueType[0];
if (blockId.equalsIgnoreCase(String.valueOf(recipientId))) {
mBlock = true;
binding.tvBlock.setText("Unblock");
break;
} else {
binding.tvBlock.setText("Block");
}
}
}
}
The problem is chatDialog.getUnreadMessageCount() giving me count 2 when I once enter in chat room and come back to my chat listing page.
Description on issue:-
Example:-
I have installed my application in two devices. when i send message from one (Device A) to other (Device B).The device B will display correct Unread count i.e 1 . Now when i click on chat dialog and get entered inside the chat room (of Device B). and come back to it's listing page and then again try to send message from Device A to device B . This time the unread count comes as 2 but it should be one as i already viewed my previous message. This get more worse if i try to open my chat room again to read the message(Device B) and get back to my listing page(Device B) after reading the message . This time if I send the message from Device A to Device B, Then the count came out as "5" just for my one message this thing is making me sick, I debugged the whole code, it's chatDialog .getUnreadMessageCount() who is returning me count "5", I don't know why my previous messages are not counted as being read messages and why everytime I open chat room one additional number gets added up inside the unread count.Please help me out , i am scratching my head from past two days.
Your help will be greatly Appreciated.
Thanks
Problem is that your AllDialogsMessageListener is not getting unregistered so unregister it by calling unregisterQbChatListeners(); when you will be opening your chat room screen . Every thing will work fine once you do that.
This what i mean :-
binding.listDialogsChats.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
QBChatDialog selectedDialog = (QBChatDialog) parent.getItemAtPosition(position);
if (currentActionMode == null) {
unregisterQbChatListeners();
ChatActivity.startForResult(((Activity) mContext), REQUEST_DIALOG_ID_FOR_UPDATE, selectedDialog);
} else {
dialogsAdapter.toggleSelection(selectedDialog);
}
}
});
private void unregisterQbChatListeners() {
if (incomingMessagesManager != null) {
incomingMessagesManager.removeDialogMessageListrener(allDialogsMessagesListener);
}
if (systemMessagesManager != null) {
systemMessagesManager.removeSystemMessageListener(systemMessagesListener);
}
dialogsManager.removeManagingDialogsCallbackListener(this);
}
cheers!!!
Please use this code below :
QBChatService.markMessagesAsRead("YOUR_DIALOG_ID", null, new QBEntityCallback<Void>() {
#Override
public void onSuccess(Void aVoid, Bundle bundle) {
QBRequestGetBuilder requestBuilder = new QBRequestGetBuilder();
requestBuilder.eq("_id", Team.getCurrent().getChatId());
QBChatService.getChatDialogs(null, requestBuilder, new QBEntityCallback<ArrayList<QBDialog>>() {
#Override
public void onSuccess(ArrayList<QBDialog> qbDialogs, Bundle bundle) {
if (qbDialogs != null && qbDialogs.size() > 0) {
QBDialog dialog = qbDialogs.get(0);//here you get your dialog with unreadMessageCount = 0
}
}
#Override
public void onError(QBResponseException e) {
}
});
}
#Override
public void onError(QBResponseException e) {
}
});
i want to query results from custom adapter by comparing query text with list in RecycleView, it successfully gets results from query then i make list of results and update the existing adapter but it does not effect anything, i use below code fot that
combinationMessagesList = createCombinationMessagesList();
combinationMessages = createCombinationMessagesList();
combinationMessages.clear();
for (int i = 0; i < combinationMessagesList.size(); i++) {
CombinationMessage message = combinationMessagesList.get(i);
if (message.getBody().toString().equals(search.getText().toString())){
combinationMessages.add(combinationMessagesList.get(i));
}
}
messagesAdapter.setList(combinationmessagesList);
messagesAdapter.notifyDataSetChanged();
}
PrivateDialogActivity
public class PrivateDialogActivity extends BaseDialogActivity {
private FriendOperationAction friendOperationAction;
private FriendObserver friendObserver;
private int operationItemPosition;
private final String TAG = "PrivateDialogActivity";
EditText search;
public static void start(Context context, User opponent, Dialog dialog) {
Intent intent = new Intent(context, PrivateDialogActivity.class);
intent.putExtra(QBServiceConsts.EXTRA_OPPONENT, opponent);
intent.putExtra(QBServiceConsts.EXTRA_DIALOG, dialog);
context.startActivity(intent);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initFields();
context = this;
if (dialog == null) {
finish();
}
setUpActionBarWithUpButton();
if (isNetworkAvailable()) {
deleteTempMessages();
}
addObservers();
initMessagesRecyclerView();
search = (EditText) findViewById(R.id.search_edittext);
Button button = (Button) findViewById(R.id.search);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showResult();
}
});
}
private void showResult() {
combinationMessagesList = createCombinationMessagesList();
combinationMessages = createCombinationMessagesList();
combinationMessages.clear();
for (int i = 0; i < combinationMessagesList.size(); i++) {
CombinationMessage message = combinationMessagesList.get(i);
if (message.getBody().toString().equals(search.getText().toString())){
combinationMessages.add(combinationMessagesList.get(i));
}
}
messagesAdapter.setList(combinationMessagesList);
messagesAdapter.notifyDataSetChanged();
}
#Override
protected void addActions() {
super.addActions();
addAction(QBServiceConsts.ACCEPT_FRIEND_SUCCESS_ACTION, new AcceptFriendSuccessAction());
addAction(QBServiceConsts.ACCEPT_FRIEND_FAIL_ACTION, failAction);
addAction(QBServiceConsts.REJECT_FRIEND_SUCCESS_ACTION, new RejectFriendSuccessAction());
addAction(QBServiceConsts.REJECT_FRIEND_FAIL_ACTION, failAction);
updateBroadcastActionList();
}
#Override
protected void onResume() {
super.onResume();
checkForCorrectChat();
if (isNetworkAvailable()) {
startLoadDialogMessages();
}
checkMessageSendingPossibility();
}
#Override
protected void onDestroy() {
super.onDestroy();
deleteObservers();
}
#Override
protected void updateActionBar() {
setOnlineStatus(opponentUser);
checkActionBarLogo(opponentUser.getAvatar(), R.drawable.placeholder_user);
}
#Override
protected void onConnectServiceLocally(QBService service) {
onConnectServiceLocally();
setOnlineStatus(opponentUser);
}
#Override
protected void onFileLoaded(QBFile file, String dialogId) {
if(!dialogId.equals(dialog.getDialogId())){
return;
}
try {
privateChatHelper.sendPrivateMessageWithAttachImage(file, opponentUser.getUserId(), null, null);
} catch (QBResponseException exc) {
ErrorUtils.showError(this, exc);
}
}
#Override
protected Bundle generateBundleToInitDialog() {
Bundle bundle = new Bundle();
bundle.putInt(QBServiceConsts.EXTRA_OPPONENT_ID, opponentUser.getUserId());
return bundle;
}
#Override
protected void initMessagesRecyclerView() {
super.initMessagesRecyclerView();
messagesAdapter = new PrivateDialogMessagesAdapter(this, friendOperationAction, combinationMessagesList, this, dialog);
messagesRecyclerView.addItemDecoration(
new StickyRecyclerHeadersDecoration((StickyRecyclerHeadersAdapter) messagesAdapter));
findLastFriendsRequest();
messagesRecyclerView.setAdapter(messagesAdapter);
scrollMessagesToBottom();
}
#Override
protected void updateMessagesList() {
initActualExtras();
checkForCorrectChat();
int oldMessagesCount = messagesAdapter.getAllItems().size();
this.combinationMessagesList = createCombinationMessagesList();
Log.d(TAG, "combinationMessagesList = " + combinationMessagesList);
messagesAdapter.setList(combinationMessagesList);
findLastFriendsRequest();
checkForScrolling(oldMessagesCount);
}
private void initActualExtras() {
opponentUser = (User) getIntent().getExtras().getSerializable(QBServiceConsts.EXTRA_OPPONENT);
dialog = (Dialog) getIntent().getExtras().getSerializable(QBServiceConsts.EXTRA_DIALOG);
}
#Override
public void notifyChangedUserStatus(int userId, boolean online) {
super.notifyChangedUserStatus(userId, online);
if (opponentUser != null && opponentUser.getUserId() == userId) {
setOnlineStatus(opponentUser);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.private_dialog_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
boolean isFriend = DataManager.getInstance().getFriendDataManager().getByUserId(
opponentUser.getUserId()) != null;
if (!isFriend && item.getItemId() != android.R.id.home) {
ToastUtils.longToast(R.string.dialog_user_is_not_friend);
return true;
}
switch (item.getItemId()) {
case R.id.action_audio_call:
callToUser(opponentUser, QBRTCTypes.QBConferenceType.QB_CONFERENCE_TYPE_AUDIO);
break;
case R.id.switch_camera_toggle:
callToUser(opponentUser, QBRTCTypes.QBConferenceType.QB_CONFERENCE_TYPE_VIDEO);
break;
default:
super.onOptionsItemSelected(item);
}
return true;
}
#Override
protected void checkMessageSendingPossibility() {
boolean enable = dataManager.getFriendDataManager().existsByUserId(opponentUser.getUserId()) && isNetworkAvailable();
checkMessageSendingPossibility(enable);
}
#OnClick(R.id.toolbar)
void openProfile(View view) {
UserProfileActivity.start(this, opponentUser.getUserId());
}
private void initFields() {
chatHelperIdentifier = QBService.PRIVATE_CHAT_HELPER;
friendOperationAction = new FriendOperationAction();
friendObserver = new FriendObserver();
initActualExtras();
// opponentUser = (User) getIntent().getExtras().getSerializable(QBServiceConsts.EXTRA_OPPONENT);
// dialog = (Dialog) getIntent().getExtras().getSerializable(QBServiceConsts.EXTRA_DIALOG);
combinationMessagesList = createCombinationMessagesList();
title = opponentUser.getFullName();
}
private void addObservers() {
dataManager.getFriendDataManager().addObserver(friendObserver);
}
private void deleteObservers() {
dataManager.getFriendDataManager().deleteObserver(friendObserver);
}
private void findLastFriendsRequest() {
((PrivateDialogMessagesAdapter) messagesAdapter).findLastFriendsRequestMessagesPosition();
messagesAdapter.notifyDataSetChanged();
}
private void setOnlineStatus(User user) {
if (user != null) {
if (friendListHelper != null) {
String offlineStatus = getString(R.string.last_seen, DateUtils.toTodayYesterdayShortDateWithoutYear2(user.getLastLogin()),
DateUtils.formatDateSimpleTime(user.getLastLogin()));
setActionBarSubtitle(
OnlineStatusUtils.getOnlineStatus(this, friendListHelper.isUserOnline(user.getUserId()), offlineStatus));
}
}
}
public void sendMessage(View view) {
sendMessage(true);
}
private void callToUser(User user, QBRTCTypes.QBConferenceType qbConferenceType) {
if (!isChatInitializedAndUserLoggedIn()) {
ToastUtils.longToast(R.string.call_chat_service_is_initializing);
return;
}
List<QBUser> qbUserList = new ArrayList<>(1);
qbUserList.add(UserFriendUtils.createQbUser(user));
CallActivity.start(PrivateDialogActivity.this, qbUserList, qbConferenceType, null);
}
private void acceptUser(final int userId) {
if (isNetworkAvailable()) {
if (!isChatInitializedAndUserLoggedIn()) {
ToastUtils.longToast(R.string.call_chat_service_is_initializing);
return;
}
showProgress();
QBAcceptFriendCommand.start(this, userId);
} else {
ToastUtils.longToast(R.string.dlg_fail_connection);
return;
}
}
private void rejectUser(final int userId) {
if (isNetworkAvailable()) {
if (!isChatInitializedAndUserLoggedIn()) {
ToastUtils.longToast(R.string.call_chat_service_is_initializing);
return;
}
showRejectUserDialog(userId);
} else {
ToastUtils.longToast(R.string.dlg_fail_connection);
return;
}
}
private void showRejectUserDialog(final int userId) {
User user = DataManager.getInstance().getUserDataManager().get(userId);
if (user == null) {
return;
}
TwoButtonsDialogFragment.show(getSupportFragmentManager(),
getString(R.string.dialog_message_reject_friend, user.getFullName()),
new MaterialDialog.ButtonCallback() {
#Override
public void onPositive(MaterialDialog dialog) {
super.onPositive(dialog);
showProgress();
QBRejectFriendCommand.start(PrivateDialogActivity.this, userId);
}
});
}
private void checkForCorrectChat() {
Dialog updatedDialog = null;
if (dialog != null) {
updatedDialog = dataManager.getDialogDataManager().getByDialogId(dialog.getDialogId());
} else {
finish();
}
if (updatedDialog == null) {
finish();
} else {
dialog = updatedDialog;
}
}
private class FriendOperationAction implements FriendOperationListener {
#Override
public void onAcceptUserClicked(int position, int userId) {
operationItemPosition = position;
acceptUser(userId);
}
#Override
public void onRejectUserClicked(int position, int userId) {
operationItemPosition = position;
rejectUser(userId);
}
}
private class AcceptFriendSuccessAction implements Command {
#Override
public void execute(Bundle bundle) {
((PrivateDialogMessagesAdapter) messagesAdapter).clearLastRequestMessagePosition();
messagesAdapter.notifyItemChanged(operationItemPosition);
startLoadDialogMessages();
hideProgress();
}
}
private class RejectFriendSuccessAction implements Command {
#Override
public void execute(Bundle bundle) {
((PrivateDialogMessagesAdapter) messagesAdapter).clearLastRequestMessagePosition();
messagesAdapter.notifyItemChanged(operationItemPosition);
startLoadDialogMessages();
hideProgress();
}
}
private class FriendObserver implements Observer {
#Override
public void update(Observable observable, Object data) {
if (data != null && data.equals(FriendDataManager.OBSERVE_KEY)) {
checkForCorrectChat();
checkMessageSendingPossibility();
}
}
}
}
it was my own mistake it code, i made the code work by changing messagesAdapter.setList(combinationmessagesList)
to
messagesAdapter.setList(combinationMessages);
I'm trying to animate a set of buttons such that they disappear sequentually on click, then performs an action based on the button clicked. The action is assigned to the animation listener which triggers on animation end. This works fine.
The problem is that I want the buttons to reappear sequentually when the activity resumes. For some reason the action assigned to the animation listener re-triggers even after setting the animation to null. What am I missing?
public class MainMenu extends ActionBarActivity {
private MenuItemBuilder menuItemBuilder;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_menu);
init();
}
private void init() {
menuItemBuilder = new MenuItemBuilder(this);
}
#Override
protected void onResume() {
super.onResume();
if (menuItemBuilder != null) {
menuItemBuilder.animateAllViewsEnter();
}
}
Below is the menu builder. I have three menu items: Load database, price list, and about. This class manages all the animations.
public MenuItemBuilder(Context context) {
this.context = context;
init();
}
private void init() {
initLoadDatabase();
initPriceList();
initAbout();
}
private View getViewFromId(int res) {
return ((Activity) context).findViewById(res);
}
private ImageButton getImageButtonFromId(int res) {
return (ImageButton) ((Activity) context).findViewById(res);
}
private void initLoadDatabase() {
final ImageButton button = getImageButtonFromId(R.id.imageLoadDatabase);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
animateAllViewsExit(ButtonType.LOAD_DATABASE);
}
});
}
private void initPriceList() {
final ImageButton button = getImageButtonFromId(R.id.imagePriceList);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
animateAllViewsExit(ButtonType.PRICE_LIST);
}
});
}
private void initAbout() {
final ImageButton button = getImageButtonFromId(R.id.imageAbout);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
animateAllViewsExit(ButtonType.ABOUT);
}
});
}
private List<View> getAnimatedViews() {
List<View> viewList = new ArrayList<>();
viewList.add(getViewFromId(R.id.imageLoadDatabase));
viewList.add(getViewFromId(R.id.priceListContainer));
viewList.add(getViewFromId(R.id.imageAbout));
return viewList;
}
public void animateAllViewsEnter() {
List<View> viewList = getAnimatedViews();
for (int i = 0; i < viewList.size(); i++) {
View view = viewList.get(i);
view.animate()
.setStartDelay((viewList.size() - i) * 250)
.alpha(1.0f);
}
}
private void animateAllViewsExit(ButtonType buttonType) {
List<View> viewList = getAnimatedViews();
for (int i = 0; i < viewList.size(); i++) {
View view = viewList.get(i);
ViewPropertyAnimator animator = view.animate()
.setStartDelay(i * 250)
.alpha(0.0f);
if (i == viewList.size() - 1) {
lastAnimation = animator;
}
}
setAnimationAction(buttonType);
}
private void setAnimationAction(final ButtonType buttonType) {
if (lastAnimation != null) {
lastAnimation.setListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
performAction(buttonType);
lastAnimation = null;
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
}
}
private void performAction(ButtonType buttonType) {
switch (buttonType) {
case LOAD_DATABASE:
// TODO to be done
break;
case PRICE_LIST:
context.startActivity(new Intent(context, PriceList.class));
break;
case ABOUT:
context.startActivity(new Intent(context, About.class));
break;
}
}
private enum ButtonType {
LOAD_DATABASE,
PRICE_LIST,
ABOUT
}
Fixed it by setting the listener to both enter and exit animations.
public void animateAllViewsEnter() {
List<View> viewList = getAnimatedViews();
for (int i = 0; i < viewList.size(); i++) {
View view = viewList.get(i);
view.animate()
.setStartDelay((viewList.size() - i) * 250)
.alpha(1.0f)
.setListener(null);
}
}
private void animateAllViewsExit(ButtonType buttonType) {
List<View> viewList = getAnimatedViews();
for (int i = 0; i < viewList.size(); i++) {
viewList.get(i).animate()
.setStartDelay(i * 250)
.alpha(0.0f)
.setListener(getAnimatorListener(i == viewList.size() - 1, buttonType));
}
}