I tried to use gridView inside bottomSheetBehavior.
I get my data asynchronize and i call to setAdapter just when the user click on my button.
The problem is that i see flicker of the data. What can i do to kill this flicker?
In my onCreate:
final ViewGroup gridViewContainer = (ViewGroup) findViewById(R.id.bottomSheetContainer);
if (gridViewContainer != null) {
gridView = (GridView) gridViewContainer.findViewById(R.id.actionGridView);
bottomSheetBehavior = BottomSheetBehavior.from(gridViewContainer);
bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
#Override
public void onStateChanged(#NonNull View bottomSheet, int newState) {
switch (newState) {
case BottomSheetBehavior.STATE_EXPANDED:
isBottomSheetQuickActionOpen = true;
gridViewContainer.requestLayout();
break;
case BottomSheetBehavior.STATE_COLLAPSED:
isBottomSheetQuickActionOpen = false;
break;
}
}
#Override
public void onSlide(#NonNull View bottomSheet, float slideOffset) {
}
});
public void onBottomBarIconClicked(View v){
switch(v.getId()){
case R.id.right_bottom_action:
if (bottomSheetBehavior != null) {
if (!isBottomSheetQuickActionOpen) {
setActionsForQuickDialog();
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
} else {
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
}
break;
}
}
private void setupQuickActionDialog() {
ActionsManager actionManager = ActionsManager.get();
List<WidgetMetaData> list = getMyList();
if (CollectionUtils.isNotEmpty(list)) {
if (gridView != null) {
adapterGridView = new AdapterGridView(ContactDetailsActivity.this, list, contact);
gridView.setAdapter(adapterGridView);
}
}
}
I found a solution that way:
1. Save member of runnable
private final Runnable runnable = new Runnable() {
#Override
public void run() {
if (!isBottomSheetQuickActionOpen) {
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
} else {
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
}
};
Save the main thread:
Handler mainHandler = new Handler(context.getMainLooper());
When button clicked, first create the gridview icons, second use the mainthread to post runnable. If we want to collapse the bottomsheetbehaviour we should remove the runnable from the queue and then just collapse by
setBottomSheetState(BottomSheetBehavior.STATE_COLLAPSED);
The function that changed:
public void onBottomBarIconClicked(View v) {
switch (v.getId()) {
case R.id.open_menu_btn:
if (bottomSheetBehavior != null) {
if (!isBottomSheetQuickActionOpen) {
setActionsForQuickDialog();
mainHandler.post(runnable);
} else {
handler.removeCallbacks(runnable);
collapseBottomSheet();
}
}
break;
}
}
Related
I have a Button, TextView(number) and an ImageView. Every time I press the button the number will increment. It will increment a lot faster when I hold the button.
I want to show an image at a specific number using ImageView at the same time making the button visible to INVISIBLE for a while to stop the increment.
The problem: If I press the button one click at a time then the below code functions well but as I hold down the button, the image appears for a very short while and continue with the numbers. And although the button is set invisible for 5 seconds, the numbers still increases(as the button is still hold).
MAIN CLASS
public class MainActivity extends AppCompatActivity {
Button button;
TextView textView;
ImageView imageView;
int i=0;
#SuppressLint("ClickableViewAccessibility")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView=findViewById(R.id.imageView);
textView=findViewById(R.id.textView);
button = findViewById(R.id.button);
button.setOnTouchListener(new RepeatListener(400, 100, new View.OnClickListener() {
#Override
public void onClick(View view) {
setText();
setImage();
}
}));
}
public void setText(){
imageView.setVisibility(View.INVISIBLE);
textView.setText(""+i);
i++;
}
public void setImage(){
if(i==10){
imageView.setImageResource(R.drawable.kitten);
imageView.setVisibility(View.VISIBLE);
buttonInvi();
}
}
public void buttonInvi(){
button.setVisibility(View.INVISIBLE);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
button.setVisibility(View.VISIBLE);
}
}, 5000); // where 1000 is equal to 1 sec (1 * 1000)
}
}
RepeatListener CLASS
public class RepeatListener implements OnTouchListener {
private Handler handler = new Handler();
private int initialInterval;
private final int normalInterval;
private final OnClickListener clickListener;
private View touchedView;
private Runnable handlerRunnable = new Runnable() {
#Override
public void run() {
if(touchedView.isEnabled()) {
handler.postDelayed(this, normalInterval);
clickListener.onClick(touchedView);
} else {
// if the view was disabled by the clickListener, remove the callback
handler.removeCallbacks(handlerRunnable);
touchedView.setPressed(false);
touchedView = null;
}
}
};
public RepeatListener(int initialInterval, int normalInterval,
OnClickListener clickListener) {
if (clickListener == null)
throw new IllegalArgumentException("null runnable");
if (initialInterval < 0 || normalInterval < 0)
throw new IllegalArgumentException("negative interval");
this.initialInterval = initialInterval;
this.normalInterval = normalInterval;
this.clickListener = clickListener;
}
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
handler.removeCallbacks(handlerRunnable);
handler.postDelayed(handlerRunnable, initialInterval);
touchedView = view;
touchedView.setPressed(true);
clickListener.onClick(view);
return true;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
handler.removeCallbacks(handlerRunnable);
touchedView.setPressed(false);
touchedView = null;
return true;
}
return false;
}
}
How about checking the visibility before increasing the counter
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
if(view.getVisibility() == View.VISIBLE){
handler.removeCallbacks(handlerRunnable);
handler.postDelayed(handlerRunnable, initialInterval);
touchedView = view;
touchedView.setPressed(true);
clickListener.onClick(view);
}
return true;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if(view.getVisibility() == View.VISIBLE){
handler.removeCallbacks(handlerRunnable);
touchedView.setPressed(false);
touchedView = null;
}
return true;
}
return false;
}
Try this line
button.setVisibility(View.GONE);
instead of
button.setVisibility(View.INVISIBLE);
Just set your listener to null when you reach a specific number and show imageview and make button invisible then after 5 seconds again set your listener and make button visible
Attention! This question is not about dynamic loading of items into a very long ListView.
This is about adding PageUP and PageDown buttons to a ListView so that user can touch the button and scroll ListView page by page. Page means all fully and partially visible items on the screen.
I have partially implemented this in the following code, but my problem is that when I have lets say 10 items of approximately same height in the listview and 7 of them fit into the first page, then when I press PgDown button, user expects that item 8 to be on top of the screen (next page), but because there are only 10 items, ListView scrolls to the bottom of the list and because there is no extra scroll space I have item number 4 on top.
What is the best solution in this situation?
Should I add one item to the end of the list which will make the last page the height of the screen or there are any better options?
Here is my code:
public class cPaginatedListViewHelper {
Activity m_parentActivity;
private ListView mList;
//controls
private LinearLayout m_PagingLL;
//buttons
private ImageButton m_btnPrevPage;
private ImageButton m_btnNextPage;
private ImageButton m_btnExitPaginatedMode;
public cPaginatedListViewHelper(ListActivity mParent) {
this.m_parentActivity = mParent;
m_btnPrevPage=(ImageButton) mParent.findViewById(R.id.btnPrevPage);
m_btnNextPage=(ImageButton) mParent.findViewById(R.id.btnNextPage);
m_btnExitPaginatedMode =(ImageButton) mParent.findViewById(R.id.btnClosePage);
if(m_btnPrevPage!=null) {
m_btnPrevPage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showSiblingPage(-1);
}
});
m_btnPrevPage.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
mList.smoothScrollToPosition(0);
return true;
}
}
);
}
if(m_btnNextPage!=null) {
m_btnNextPage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showSiblingPage(1);
}
});
m_btnNextPage.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
mList.smoothScrollToPosition(mList.getCount());
return true;
}
}
);
}
m_btnExitPaginatedMode.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setEnabled(false);
m_PagingLL.setVisibility(View.GONE);
}
});
mList=mParent.getListView();
m_PagingLL = (LinearLayout) mParent.findViewById(R.id.pageControls);
}
public void updateControlsVisibility()
{
ViewTreeObserver observer = mList.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (willMyListScroll()) {
boolean psm = isEnabled();
//enable or disable
m_PagingLL.setVisibility( psm ? View.VISIBLE : View.GONE);
((View)mList).setVerticalScrollbarPosition(psm ? View.SCROLLBAR_POSITION_LEFT: View.SCROLLBAR_POSITION_RIGHT);
}
else
{
m_PagingLL.setVisibility(View.GONE);
((View)mList).setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_RIGHT);
}
}
});
}
private boolean willMyListScroll() {
try {
int pos = mList.getLastVisiblePosition();
if (mList.getChildAt(pos).getBottom() > mList.getHeight()) {
return true;
} else {
return false;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
private void showSiblingPage(int shift)
{
if(mList!=null) {
int iScrollPageHeight = mList.getHeight();
mList.scrollListBy(iScrollPageHeight * shift);
}
}
public void setEnabled(boolean psm) {
MyApp.Pref.edit().putBoolean("PSModeEnabled", psm).commit();
}
public boolean isEnabled(){
return MyApp.Pref.getBoolean("PSModeEnabled", false);
}
public void pagedScrollEnableDisable() {
boolean pagingEnabled = isEnabled();
pagingEnabled=!pagingEnabled;
setEnabled(pagingEnabled);
m_PagingLL.setVisibility( pagingEnabled ? View.VISIBLE : View.GONE);
updateControlsVisibility();
}
}
I finished up with using ListView's footer with variable height as shown in the following code:
LayoutInflater inflater = m_parentActivity.getLayoutInflater();
m_footerView = inflater.inflate(R.layout.listview_paged_overscroll, mList, false );
ViewGroup.LayoutParams lp =m_footerView.getLayoutParams();
if(m_tvPageNum!=null) recalcPagination();
if(lp!=null) lp.height = m_extraScrollFooterHeight;
int iFooters = mList.getFooterViewsCount();
if(iFooters==0) mList.addFooterView(m_footerView);
I am developing an android application, in that i using displaying pull notifications. I am getting the list of notification from backend and displaying in the form of custom list view.The problem is i am providing a button to delete particular notification from list view when ever i tried to delete the notification at any index it is deleting but after scrolling the entire list view is getting refreshed. How can i handle this?
one more thing is i am not using notifysetdatachange() anywhere.
public class NotificationListViewHolder extends BaseListAdapter.ViewHolder {
//timeStamp, userName;
public final CircleImageView profilePicture;
public final TextView timeStamp;
public final ImageView deleteNotification;
public final ProgressBar progressBar;
public final RelativeLayout notificationListItem;
public TextView requirement;
public LinearLayout clickableArea;
NotificationListViewHolder viewHolder;
NotificationListAdapter listAdapter;
public NotificationListViewHolder(View view, BaseListAdapterListener listener, NotificationListAdapter listAdapter) {
super(view, listener);
requirement = view.findViewById(R.id.requirement);
profilePicture = view.findViewById(R.id.profile_picture);
notificationListItem = view.findViewById(R.id.notification_list_item);
deleteNotification = view.findViewById(R.id.delete_notification);
progressBar = view.findViewById(R.id.progressBar);
clickableArea = view.findViewById(R.id.clickable_area);
timeStamp = view.findViewById(R.id.time_stamp);
this.listAdapter = listAdapter;
}
public void bind(final Notification entry, NotificationListViewHolder holder) {
try {
if (holder.notificationListItem.getTag() == null) {
holder.notificationListItem.setTag(holder);
} else {
viewHolder = (NotificationListViewHolder) holder.notificationListItem.getTag();
}
viewHolder.progressBar.setVisibility(entry.isSelected()
? View.VISIBLE : View.GONE);
viewHolder.deleteNotification.setVisibility(entry.isSelected()
? View.GONE : View.VISIBLE);
viewHolder.requirement.setText(entry.getRequirement());
if (entry.getRoleName().equals("")) {
viewHolder.timeStamp.setText(TimeFormat.getTimeStamp(entry.getTimestamp(), TimeFormatTypes.FORMAT_DESCRIPTION) + "");
} else {
viewHolder.timeStamp.setText(entry.getRoleName() + " - " + TimeFormat.getTimeStamp(entry.getTimestamp(), TimeFormatTypes.FORMAT_DESCRIPTION) + "");
}
if (viewHolder.profilePicture != null && !entry.getProfileUrl().equalsIgnoreCase("")) {
Picasso.with(D4E.getContext()).load(D4E.getContext().getResources().getString(R.string.liferay_server) + entry.getProfileUrl()).placeholder(R.drawable.default_profile_pic)
.error(R.drawable.default_profile_pic).into(viewHolder.profilePicture);
}
if (entry.getType() == 1) { // light grey , my post notifications || other post notification
viewHolder.notificationListItem.setBackgroundColor(Color.parseColor("#C8FAD2"));
viewHolder.requirement.setTextColor(Color.parseColor("#030303"));
} else if (entry.getType() == 2) {
// the posts by others
/* viewHolder.notificationListItem.setBackgroundColor(Color.parseColor("#DCDCDC"));
viewHolder.requirement.setTextColor(Color.parseColor("#030303"));*/
} else if (entry.getType() == 0) { // dark grey , admin
viewHolder.notificationListItem.setBackgroundColor(Color.parseColor("#FAFAC8"));
viewHolder.requirement.setTextColor(Color.parseColor("#030303"));
}
viewHolder.clickableArea.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
entry.setSelected(true);
deleteNotification();
viewHolder.progressBar.setVisibility(View.VISIBLE);
viewHolder.deleteNotification.setVisibility(View.GONE);
}
private void deleteNotification() {
Session session = SessionContext.createSessionFromCurrentSession();
session.setCallback(new Callback() {
#Override
public void inBackground(Response response) {
((Activity) D4E.getContext()).runOnUiThread(new Runnable() {
#Override
public void run() {
try {
viewHolder.progressBar.setVisibility(View.GONE);
AnimatorUtil.animate(viewHolder/*, true*/);
listAdapter.getEntries().remove(listAdapter.getEntries().get(viewHolder.getLayoutPosition()));
listAdapter.notifyItemRemoved(viewHolder.getLayoutPosition());
UserInfoController.initializeUserInfoController().getUserInfo().setNotificationCount(listAdapter.getEntries().size());
/* listAdapter.notifyDataSetChanged();
listAdapter.getEntries().remove(listAdapter.getEntries().get(viewHolder.getLayoutPosition()));
listAdapter.notifyItemRemoved(viewHolder.getLayoutPosition());
listAdapter.notifyItemRangeChanged(viewHolder.getLayoutPosition(), listAdapter.getEntries().size());
listAdapter.notifyDataSetChanged();
UserInfoController.initializeUserInfoController().getUserInfo().setNotificationCount(listAdapter.getEntries().size());*/
/*if (listAdapter.getEntries().size() == 0)
(() D4E.getContext()).onNoListItem();*/
} catch (Exception e) {
Log.e("Ex:Noti_List_Adp", "" + e.toString());
}
}
});
}
#Override
public void doFailure(Exception exception) {
viewHolder.progressBar.setVisibility(View.GONE);
viewHolder.deleteNotification.setVisibility(View.VISIBLE);
entry.setSelected(false);
}
});
try {
new DeccategoryService(session).DeleteNotification(Long.parseLong(entry.getNotificationId()));
} catch (Exception e) {
e.printStackTrace();
}
}
});
/* if (holder.notificationListItem.getTag() == null) {
holder.notificationListItem.setTag(holder);
} else {
viewHolder = (NotificationListViewHolder) holder.notificationListItem.getTag();
}*/
/* viewHolder.clickableArea.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
entry.setSelected(true);
// adapter.removeItem(entry,getAdapterPosition());
openDeleteNotification();
viewHolder.progressBar.setVisibility(View.VISIBLE);
viewHolder.deleteNotification.setVisibility(View.GONE);
}
private void openDeleteNotification() {
Session session = SessionContext.createSessionFromCurrentSession();
session.setCallback(new Callback() {
#Override
public void inBackground(Response response) {
((Activity) D4E.getContext()).runOnUiThread(new Runnable() {
#Override
public void run() {
viewHolder.progressBar.setVisibility(View.GONE);
adapter.removeItem(entry, getAdapterPosition());
}
});
}
#Override
public void doFailure(Exception exception) {
viewHolder.progressBar.setVisibility(View.GONE);
viewHolder.deleteNotification.setVisibility(View.VISIBLE);
entry.setSelected(false);
}
});
try {
new DeccategoryService(session).DeleteNotification(Long.parseLong(entry.getNotificationId()));
} catch (Exception e) {
e.printStackTrace();
}
}
});*/
viewHolder.progressBar.setVisibility(entry.isSelected()
? View.VISIBLE : View.GONE);
viewHolder.deleteNotification.setVisibility(entry.isSelected()
? View.GONE : View.VISIBLE);
viewHolder.requirement.setText(entry.getRequirement());
if (entry.getRoleName().equals("")) {
viewHolder.timeStamp.setText(TimeFormat.getTimeStamp(entry.getTimestamp(), TimeFormatTypes.FORMAT_DESCRIPTION) + "");
} else {
viewHolder.timeStamp.setText(entry.getRoleName() + " - " + TimeFormat.getTimeStamp(entry.getTimestamp(), TimeFormatTypes.FORMAT_DESCRIPTION) + "");
}
if (viewHolder.profilePicture != null && !entry.getProfileUrl().equalsIgnoreCase("")) {
Picasso.with(D4E.getContext()).load(D4E.getContext().getResources().getString(R.string.liferay_server) + entry.getProfileUrl()).placeholder(R.drawable.default_profile_pic)
.error(R.drawable.default_profile_pic).into(viewHolder.profilePicture);
}
if (entry.getType() == 1) {
viewHolder.notificationListItem.setBackgroundColor(Color.parseColor("#F2F2F2"));
viewHolder.requirement.setTextColor(Color.parseColor("#030303"));
} else if (entry.getType() == 2) {
/* viewHolder.notificationListItem.setBackgroundColor(Color.parseColor("#DCDCDC"));
viewHolder.requirement.setTextColor(Color.parseColor("#030303"));*/
} else {
viewHolder.notificationListItem.setBackgroundColor(Color.parseColor("#FFFFFF"));//admin post color
}
// FontStyle.getInstance().FontStyleByGroupOfIds(view.getContext(), new int[]{R.id.notification_list_item}, view);
} catch (Exception e) {
Log.e("Exception", e.toString());
}
}
public void createDialog() {
final AlertDialog.Builder builder = new AlertDialog.Builder(D4E.getContext());
builder.setTitle("Alert!");
builder.setMessage("Message from Admin");
builder.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
});
builder.show();
}
}
public class Notifications extends Scheduler implements ScreenletListListener, SearchView.OnQueryTextListener, NoListListener, UpdateLogout {
public static boolean isInSettingsPage;
public static long notificationId;
public static String notificationSearchKeyword = "";
public static boolean notificationSearchActivated = false;
public static boolean navigatedFromPush = false;
ArrayList<digital.engineers.club.models.Notifications> notificationsModel;
BottomSheetDialog dialog;
View dialogView;
Menu menu;
GenericScreenlet screenlet;
SearchView searchView;
MenuItem searchMenuItem;
LinearLayout container;
View screenletView, noIntimationView;
private boolean shudRefreshOnResume = false;
//Push test
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notifications);
setContext(this);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
container = findViewById(R.id.ns);
D4E.setContext(this);
FontStyle.getInstance().setContext(this);
getSupportActionBar().setTitle(FontStyle.getInstance()
.getSpannableString(getSupportActionBar().getTitle().toString()));
container = findViewById(R.id.container);
noIntimationView = View.inflate(this, R.layout.no_list_intimation, null);
refreshNotifications();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.notification_menu, menu);
this.menu = menu;
final MenuItem menuItem = menu.findItem(R.id.nsettings);
BitmapDrawable icon = (BitmapDrawable) menuItem.getIcon();
Drawable drawable = DrawableCompat.wrap(icon);
DrawableCompat.setTint(drawable, getResources().getColor(R.color.white));
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchMenuItem = menu.findItem(R.id.search);
searchView = (SearchView) searchMenuItem.getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setOnQueryTextListener(this);
searchView.setSubmitButtonEnabled(false);
searchView.setIconifiedByDefault(true);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
if (isInSettingsPage) {
resetNotificationPage();
isInSettingsPage = false;
} else {
if (navigatedFromPush) {
startActivity(new Intent(this, HomeScreen.class));
navigatedFromPush = false;
} else
finish();
}
} else if (item.getItemId() == R.id.search) {
} else if (item.getItemId() == R.id.nsettings) {
isInSettingsPage = true;
loadSettings();
}
return super.onOptionsItemSelected(item);
}
public void loadSettings() {
FontStyle.getInstance().setContext(this);
getSupportActionBar().setTitle(FontStyle.getInstance().getSpannableString("Notification Settings"));
container.removeAllViews();
if (searchMenuItem.isActionViewExpanded())
searchMenuItem.collapseActionView();
menu.getItem(0).setVisible(false);
menu.getItem(1).setVisible(false);
getFragmentManager().beginTransaction().replace(R.id.container, new NotificationSettingsFragment()).commit();
}
private void openbootomsheet() {
dialog = new BottomSheetDialog(Notifications.this);
dialogView = View.inflate(Notifications.this, R.layout.search_posts, null);
dialogView.findViewById(R.id.search_by_time_layout);
dialog.setContentView(dialogView);
((Spinner) dialogView.findViewById(R.id.posted_time)).setAdapter(new ArrayAdapter<String>(Notifications.this, android.R.layout.simple_list_item_1,
android.R.id.text1,
getResources().getStringArray(R.array.day_search)));
((Spinner) dialogView.findViewById(R.id.role)).setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
android.R.id.text1,
getResources().getStringArray(R.array.roles)));
dialog.show();
dialogView.findViewById(R.id.close_button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialogView.findViewById(R.id.search_button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
}
#Override
public void onListPageReceived(int startRow, int endRow, List<Object> entries, int rowCount) {
// Toast.makeText(this,"Success",Toast.LENGTH_LONG).show();
//UserInfoController.initializeUserInfoController().getUserInfo().setNotificationCount(0);
UserInfoController.initializeUserInfoController().getUserInfo().setNotificationCount(entries.size());
if (entries.size() == 0) {
showNoNotificationIntimation();
}
/*screenlet.setVisibility(entries.size() > 0 ? View.VISIBLE : View.GONE);
((LinearLayout) findViewById(R.id.no_list_layout)).setVisibility(entries.size() > 0 ? View.GONE : View.VISIBLE);*/
}
#Override
public void onListItemSelected(Object element, View view) {
Notification notification = (Notification) element;
if (notification != null) {
if (((Notification) element).getType() != 0) {
notificationId = Long.parseLong(notification.getNotificationId());
NewPost.postType = (SessionContext.getUserId() == Long.parseLong(notification.getPostedUserId())) ?
getResources().getString(R.string.post_type_my_post) :
getResources().getString(R.string.post_type_relevant_post);
Map<String, Object> postMap = new HashMap<>();
postMap.put("threadId", notification.getThreadId());
postMap.put("profileUrl", SessionContext.getUserId() == Long.parseLong(notification.getPostedUserId()) ?
UserInfoController.initializeUserInfoController().getUserInfo().getProfileUrl() :
notification.getProfileUrl());
postMap.put("firstName", notification.getFirstName());
postMap.put("lastName", notification.getLastName());
postMap.put("categoryId", notification.getCategoryId());
postMap.put("timestamp", notification.getTimestamp());
postMap.put("subject", notification.getSubject());
postMap.put("threadStatus", notification.getThreadStatus());
postMap.put("userId", String.valueOf(SessionContext.getUserId()));
postMap.put("postedUserId", notification.getPostedUserId());
postMap.put("userName", notification.getUserName());
postMap.put("roleName", notification.getRoleName());
// postMap.put("attachment",notification.getAttachment());
ViewThread.post = new Post(postMap);
ViewThread.post.setAttachment(notification.getAttachment());
NewPost.currentPostId = ViewThread.post.getThreadId();
NewPost.currentPosition = (SessionContext.getUserId() == Long.parseLong(notification.getPostedUserId())) ?
0 : 1; // View Pager position
NewPost.postedUserId = Long.parseLong(ViewThread.post.getPostedUserId());
HomeScreen.categoryId = Long.parseLong(ViewThread.post.getCategoryId());
Intent intent = new Intent(Notifications.this, ViewThread.class);
intent.putExtra("THREAD", ViewThread.post);
startActivity(intent);
} else {
createDialog(notification.getRequirement());
}
}
}
#Override
public void error(Exception e, String userAction) {
// Toast.makeText(this,e.toString(),Toast.LENGTH_LONG).show();
}
#Override
public void onListPageFailed(int startRow, Exception e) {
// Toast.makeText(this,e.toString(),Toast.LENGTH_LONG).show();
}
#Override
public void interactorCalled() {
}
#Override
protected void onResume() {
super.onResume();
if (isScreenOn(this) && hasTimedOut) {
initializeTimer();
resetTimeOut();
startSessionTimeCountDown();
}
if (shudRefreshOnResume) {
if (!isInSettingsPage) {
refreshNotifications();
shudRefreshOnResume = false;
} else {
loadSettings();
}
}
}
#Override
protected void onPause() {
super.onPause();
shudRefreshOnResume = true;
}
#Override
public boolean onQueryTextSubmit(String query) {
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
if (newText.length() > 3) {
notificationSearchKeyword = newText;
notificationSearchActivated = true;
refreshNotifications();
} else if (newText.length() == 0) {
notificationSearchKeyword = "";
notificationSearchActivated = false;
refreshNotifications();
}
return true;
}
public void refreshNotifications() {
container.removeAllViews();
View notificationScreenlet = View.inflate(this, R.layout.notification_list_screenlet, null);
screenlet = notificationScreenlet.findViewById(R.id.notification_list_screenlet);
screenlet.setPagination();
screenlet.setListener(this);
container.addView(notificationScreenlet);
}
public void resetNotificationPage() {
FontStyle.getInstance().setContext(this);
getSupportActionBar().setTitle(FontStyle.getInstance().getSpannableString("Notifications"));
menu.getItem(0).setVisible(true);
menu.getItem(1).setVisible(true);
refreshNotifications();
notificationSearchActivated = false;
}
private void setItemsVisibility(Menu menu, MenuItem exception, boolean visible) {
for (int i = 0; i < menu.size(); ++i) {
MenuItem item = menu.getItem(i);
if (item != exception) item.setVisible(visible);
}
}
#Override
public void onBackPressed() {
notificationSearchActivated = false;
if (isInSettingsPage) {
resetNotificationPage();
isInSettingsPage = false;
} else {
if (navigatedFromPush) {
startActivity(new Intent(this, HomeScreen.class));
navigatedFromPush = false;
} else
finish();
}
}
public void createDialog(String message) {
final AlertDialog.Builder builder = new AlertDialog.Builder(D4E.getContext());
builder.setTitle("Message from Admin");
builder.setMessage(message);
builder.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
});
builder.show();
}
public void showNoNotificationIntimation() {
container.removeAllViews();
noIntimationView.findViewById(R.id.no_list_layout).setLayoutParams(new LinearLayout.LayoutParams
(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
container.addView(noIntimationView);
}
#Override
public void onNoListItem() {
showNoNotificationIntimation();
}
#Override
public void onUpdatedLogoutToServer() {
//if (SessionHelper.initializeSessionHelper().logout()) {
DisplayDialog.display(this);
/*} else {
Log.e("LogoutErr", "Homescreen: Unable to Logout");
}*/
}
#Override
public void onError(Exception e) {
Toast.makeText(getApplicationContext(), "Unable to logout from scheduler", Toast.LENGTH_SHORT).show();
}
when you delete item form list that time remove that item form list and notify adapter.
like below code ... when i am delete any item form recycler view ..
yourlist.remove(yourlist.get(yourlist.indexOf(data))); // common data that pass in list.if List<String> that pass string data if object them pass that object data.
youradapter.notifyDataSetChanged();
As per documentation you should not use this method with viewholder. you should use getAdapterposition() to get position of row.
getLayoutPosition added in version 22.1.0
int getLayoutPosition ()
Returns the position of the ViewHolder in terms of the latest layout
pass.
This position is mostly used by RecyclerView components to be
consistent while RecyclerView lazily processes adapter updates.
For performance and animation reasons, RecyclerView batches all
adapter updates until the next layout pass. This may cause mismatches
between the Adapter position of the item and the position it had in
the latest layout calculations.
LayoutManagers should always call this method while doing calculations
based on item positions. All methods in RecyclerView.LayoutManager,
RecyclerView.State, RecyclerView.Recycler that receive a position
expect it to be the layout position of the item.
If LayoutManager needs to call an external method that requires the
adapter position of the item, it can use getAdapterPosition() or
convertPreLayoutPositionToPostLayout(int).
In your use case, since your data is related to your adapter contents (and I assume that data is changed at the same time with adapter changes), you should be using adapterPosition.
Replace this lines
listAdapter.getEntries().remove(listAdapter.getEntries().get(viewHolder.getLayoutPosition()));
listAdapter.notifyItemRemoved(viewHolder.getLayoutPosition());
with
listAdapter.getEntries().remove(listAdapter.getEntries().get(viewHolder.getAdapterPosition()));
listAdapter.notifyItemRemoved(viewHolder.getAdapterPosition());
I want to Show a Tabbed based inside Dialog so for this I use This Library.
I am able to populate my Dialog and also Tab is switching from Tab_1 to Tab_2. But when I am clicking on its Cancel, Ok or Neutral Button, I am not getting Toast.
Please guide me how can I use Initialize Fragments and Toast on Button Click in my BaseAdapter.
My code is here
public class ContactListAdapter extends BaseAdapter implements ISimpleDialogListener, ISimpleDialogCancelListener,IFragmentListener {
slidingListItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
contactListItems = contactList.get(position);
String id_attende = contactListItems.getPhone();
String id_attende_name = contactListItems.getName();
TabDialogFragment.createBuilder(context, mFragmentManager)
.setTitle(id_attende_name)
.setSubTitle(id_attende)
.setTabButtonText(new CharSequence[]{"Calendar", "Summary"})
.setPositiveButtonText("Ok")
.setNegativeButtonText("Cancel")
.setNeutralButtonText("Neutral")
.setRequestCode(REQUEST_TABBED_DIALOG)
.show();
}
});
return convertView;
}
#Override
public void onCancelled(int requestCode) {
switch (requestCode) {
case REQUEST_TABBED_DIALOG:
Toast.makeText(context, "Dialog cancelled", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
#Override
public void onNegativeButtonClicked(int requestCode) {
if (requestCode == REQUEST_TABBED_DIALOG) {
Toast.makeText(context, "Negative button clicked", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onNeutralButtonClicked(int requestCode) {
if (requestCode == REQUEST_TABBED_DIALOG) {
Toast.makeText(context, "Neutral button clicked", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onPositiveButtonClicked(int requestCode) {
if (requestCode == REQUEST_TABBED_DIALOG) {
Toast.makeText(context, "Positive button clicked", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFragmentViewCreated(Fragment fragment) {
int selectedTabPosition = fragment.getArguments().getInt(PageFragment.ARG_DAY_INDEX, 0);
View rootContainer = fragment.getView().findViewById(R.id.root_container);
Log.i(TAG, "Position: " + selectedTabPosition);
switch (selectedTabPosition) {
case 0:
selectedTabPositionZeroCase(rootContainer);
break;
case 1:
selectedTabPositionOneCase(rootContainer);
break;
default:
break;
}
}
private void selectedTabPositionZeroCase(View rootContainer) {
// add view in container for first tab
LayoutInflater li = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View tabProductDetailLayout = li.inflate(R.layout.tab_one_layout, (ViewGroup) rootContainer);
TextView textView = (TextView) tabProductDetailLayout.findViewById(R.id.text_view);
textView.setText("hello: tab1");
}
private void selectedTabPositionOneCase(View rootContainer) {
// add view in container for second tab
LayoutInflater li = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View tabProductDetailLayout2 = li.inflate(R.layout.tab_one_layout, (ViewGroup) rootContainer);
TextView textView1 = (TextView) tabProductDetailLayout2.findViewById(R.id.text_view);
textView1.setText("hello: tab2");
}
#Override
public void onFragmentAttached(Fragment fragment) {
mMyScheduleFragments.add(fragment);
}
#Override
public void onFragmentDetached(Fragment fragment) {
mMyScheduleFragments.remove(fragment);
}
}
Actually from the link, you have provided, They are passing the MainActivity.this where you are passing context and there is a problem. So as per my suggestion just implement these callbacks in your MainActivity.java class instead of Adapter class.
I am pretty curious about the behavior of the BottomSheetDialog when it is dismissed : when the user draggs it down to hide it, it will remain hidden, even if bottomSheetDialog#show() is called after. This only happens when it is dragged down, not when the user touches outside or when bottomSheetDialog#dismiss() is called programatically.
It is really annoying because I have a pretty big bottomSheetDialog with a recyclerview inside, and I have to create a new one every time I want to show the bottomSheetDialog.
So instead of just doing this :
if(bottomSheetDialog != null){
bottomSheetDialog.show();
else{
createNewBottomSheetDialog();
}
I have to create one every time.
Am I missing something or is it the normal behavior ? (Btw I use appcompat-v7:23.2.1)
So I finally managed to solve this problem by looking directly into the BottomSheetDialog implementation, and I discovered it was nothing but a simple Dialog wrapped into a regular BottomSheet.
The problem was in the BottomSheetCallBack :
#Override
public void onStateChanged(#NonNull View bottomSheet,
#BottomSheetBehavior.State int newState) {
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
dismiss();
}
}
The problem occurs when the state HIDDEN is reached which happens when the dialog is dismissed by being dragged down. After that the dialog stays hidden even if bottomSheetDialog.show() is called. The most simple fix I found was to remove this state and replace it by the COLLAPSED state.
I create a classCustomBottomSheetDialog, copied the entire BottomSheetDialog class and added a single line to fix the problem :
#Override
public void onStateChanged(#NonNull View bottomSheet,
#BottomSheetBehavior.State int newState) {
if (newState == CustomBottomSheetBehavior.STATE_HIDDEN) {
dismiss();
bottomSheetBehavior.setState(CustomBottomSheetBehavior.STATE_COLLAPSED);
}
}
Here is the final code:
public class CustomBottomSheetDialog extends AppCompatDialog {
public CustomBottomSheetDialog (#NonNull Context context) {
this(context, 0);
}
public CustomBottomSheetDialog (#NonNull Context context, #StyleRes int theme) {
super(context, getThemeResId(context, theme));
// We hide the title bar for any style configuration. Otherwise, there will be a gap
// above the bottom sheet when it is expanded.
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
}
protected CustomBottomSheetDialog (#NonNull Context context, boolean cancelable,
OnCancelListener cancelListener) {
super(context, cancelable, cancelListener);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
}
#Override
public void setContentView(#LayoutRes int layoutResId) {
super.setContentView(wrapInBottomSheet(layoutResId, null, null));
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setLayout(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
}
#Override
public void setContentView(View view) {
super.setContentView(wrapInBottomSheet(0, view, null));
}
#Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
super.setContentView(wrapInBottomSheet(0, view, params));
}
private View wrapInBottomSheet(int layoutResId, View view, ViewGroup.LayoutParams params) {
final CoordinatorLayout coordinator = (CoordinatorLayout) View.inflate(getContext(),
R.layout.design_bottom_sheet_dialog, null);
if (layoutResId != 0 && view == null) {
view = getLayoutInflater().inflate(layoutResId, coordinator, false);
}
FrameLayout bottomSheet = (FrameLayout) coordinator.findViewById(R.id.design_bottom_sheet);
BottomSheetBehavior.from(bottomSheet).setBottomSheetCallback(mBottomSheetCallback);
if (params == null) {
bottomSheet.addView(view);
} else {
bottomSheet.addView(view, params);
}
// We treat the CoordinatorLayout as outside the dialog though it is technically inside
if (shouldWindowCloseOnTouchOutside()) {
coordinator.findViewById(R.id.touch_outside).setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View view) {
if (isShowing()) {
cancel();
}
}
});
}
return coordinator;
}
private boolean shouldWindowCloseOnTouchOutside() {
if (Build.VERSION.SDK_INT < 11) {
return true;
}
TypedValue value = new TypedValue();
//noinspection SimplifiableIfStatement
if (getContext().getTheme()
.resolveAttribute(android.R.attr.windowCloseOnTouchOutside, value, true)) {
return value.data != 0;
}
return false;
}
private static int getThemeResId(Context context, int themeId) {
if (themeId == 0) {
// If the provided theme is 0, then retrieve the dialogTheme from our theme
TypedValue outValue = new TypedValue();
if (context.getTheme().resolveAttribute(
R.attr.bottomSheetDialogTheme, outValue, true)) {
themeId = outValue.resourceId;
} else {
// bottomSheetDialogTheme is not provided; we default to our light theme
themeId = R.style.Theme_Design_Light_BottomSheetDialog;
}
}
return themeId;
}
private BottomSheetBehavior.BottomSheetCallback mBottomSheetCallback
= new BottomSheetBehavior.BottomSheetCallback() {
#Override
public void onStateChanged(#NonNull View bottomSheet,
#BottomSheetBehavior.State int newState) {
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
dismiss();
bottomSheetBehavior.setState(CustomBottomSheetBehavior.STATE_COLLAPSED);
}
}
#Override
public void onSlide(#NonNull View bottomSheet, float slideOffset) {
}
};
}
Update: The problem has been resolved at some version of the support library. I don't really know the exact version that fixes it but in 27.0.2 it is fixed.
Note: The URL does no longer refer to the issue described due to some modification on the URL schema by Google.
A workaround better than copying the whole class just to add a single line
// Fix BottomSheetDialog not showing after getting hidden when the user drags it down
myBottomSheetDialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialogInterface) {
BottomSheetDialog bottomSheetDialog = (BottomSheetDialog) dialogInterface;
FrameLayout bottomSheet = (FrameLayout) bottomSheetDialog
.findViewById(android.support.design.R.id.design_bottom_sheet);
BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_COLLAPSED);
}
});
see: https://code.google.com/p/android/issues/detail?id=202396#c7
I have sample demo I hope that is useful.
public class BottomListMenu extends BottomSheetDialog {
private List<MenuDTO> menuList;
private OnMenuItemTapped menuTapListener;
public BottomListMenu(#NonNull Context context, List<MenuDTO> menuList, OnMenuItemTapped menuTapListener) {
super(context);
this.menuList = menuList;
this.menuTapListener = menuTapListener;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_menu_list);
RecyclerView rcvList = (RecyclerView) findViewById(R.id.rcv_menu_list);
rcvList.setLayoutManager(new LinearLayoutManager(getContext()));
BottomSheetMenuListAdapter adapter = new BottomSheetMenuListAdapter(getContext(), this, menuList, menuTapListener);
rcvList.setAdapter(adapter);
}
}
--- Use ---
BottomListMenu menu = new BottomListMenu(MainActivity.this, MenuUtils.getListMenu(MainActivity.this), new OnMenuItemTapped() {
#Override
public void onClickMenuItem(MenuDTO menu) {
if (menu.getMenuTitle().equals(getString(R.string.menu_edit))) {
Toast.makeText(MainActivity.this, "Edit Clicked", Toast.LENGTH_SHORT).show();
} else if (menu.getMenuTitle().equals(getString(R.string.menu_delete))) {
Toast.makeText(MainActivity.this, "Delete Clicked", Toast.LENGTH_SHORT).show();
} else if (menu.getMenuTitle().equals(getString(R.string.menu_attach))) {
Toast.makeText(MainActivity.this, "Attach Clicked", Toast.LENGTH_SHORT).show();
}
}
});
menu.show();
-- Full Sample Code Available Here --
https://github.com/bita147/BottomSheetDialog