Skip to content

Instantly share code, notes, and snippets.

@dron247
Created January 14, 2019 07:50
Show Gist options
  • Save dron247/57e1fd18e7f0bb9d67d4c5dd1cb2bd4e to your computer and use it in GitHub Desktop.
Save dron247/57e1fd18e7f0bb9d67d4c5dd1cb2bd4e to your computer and use it in GitHub Desktop.
Внизу. Пока сдвигаешь, рисуется бэк с крестиком, затем вот тот addPendingItem заменяет элемент на меню, тоесть вместо текста там лэйаут с кнопками, не суть важно
package com.dpcat237.tidinio.ui.fragments.main;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.dpcat237.tidinio.R;
import com.dpcat237.tidinio.core.Constants;
import com.dpcat237.tidinio.core.bus.EventBus;
import com.dpcat237.tidinio.core.controller.UserController;
import com.dpcat237.tidinio.core.helper.SubscribeHelper;
import com.dpcat237.tidinio.core.realm.repository.FeedRepository;
import com.dpcat237.tidinio.core.retrofit.Responces.NewpselFeed;
import com.dpcat237.tidinio.events.ArticleReadedChange;
import com.dpcat237.tidinio.events.ArticleViewPreferenceChanged;
import com.dpcat237.tidinio.events.FeedsReceivedEvent;
import com.dpcat237.tidinio.events.UpdateArticle;
import com.dpcat237.tidinio.events.UpdateArticleFailureEvent;
import com.dpcat237.tidinio.inject.Injector;
import com.dpcat237.tidinio.ui.adapters.FeedsAdapter;
import com.dpcat237.tidinio.ui.fragments.dialog.EditFeedNameDialog;
import com.squareup.otto.Subscribe;
import javax.inject.Inject;
import butterknife.Bind;
import butterknife.ButterKnife;
/**
* Created by Alexey on 15.08.2016.
*/
public class FeedsArticles extends Fragment {
@Bind(R.id.feeds)
RecyclerView feeds;
@Bind(R.id.swipeRefreshLayout)
SwipeRefreshLayout swipeRefreshLayout;
@Inject
UserController userController;
@Inject
EventBus bus;
Activity activity;
@Inject
SubscribeHelper subscribeHelper;
@Inject
FeedRepository feedsRe;
@Inject
SharedPreferences preferences;
boolean showErrorMessage = false;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_feedarticle, null, false);
ButterKnife.bind(this, view);
Injector.INSTANCE.getApplicationComponent().inject(this);
boolean hideEmpty = preferences.getInt(//decide if hiding empty is necessary
Constants.Preferences.ARTICLE_LIST_FILTER_MODE,
Constants.PreferencesArticle.ARTICLE_PREFERENCE_SHOW_ALL
) == Constants.PreferencesArticle.ARTICLE_PREFERENCE_SHOW_UNREAD;
activity = getActivity();
final FeedsAdapter adapter = new FeedsAdapter(hideEmpty);
//listener for items swipe menu actions
adapter.setItemMenuListener(new FeedsAdapter.FeedItemMenuClickedListener() {
@Override
public void onDeleteClicked(final String apiId) {
//show confirmation
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getContext());
dialogBuilder.setTitle(R.string.dialogs_delete_feed_title);
dialogBuilder.setMessage(R.string.dialogs_delete_feed_message);
dialogBuilder.setNegativeButton(R.string.button_cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
dialogBuilder.setPositiveButton(R.string.button_delete, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
subscribeHelper.unsubscribe(apiId, new SubscribeHelper.FeedRemovedListener() {
@Override
public void done(boolean isError) {
if (!isError) {
((FeedsAdapter) feeds.getAdapter()).updateDataSource();
Toast.makeText(getContext(), R.string.message_feed_delete_success, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getContext(), R.string.message_feed_delete_error, Toast.LENGTH_SHORT).show();
}
}
});//assign work to subscription controller
}
});
dialogBuilder.create().show();
adapter.resetPendingItems();//close item menu
}
@Override
public void onEditClicked(final String apiId) {
final NewpselFeed feed = feedsRe.getFeed(apiId);//get the feed item
adapter.resetPendingItems();//close menu
//show editor
EditFeedNameDialog editFeedNameDialog = EditFeedNameDialog.newInstance();
editFeedNameDialog.setFeedName(feed.getTitle());
editFeedNameDialog.setResultListener(new EditFeedNameDialog.EditFeedNameDialogResultListener() {
@Override
public void onResult(String newName) {
//assign work to controller when user confirmed the change
subscribeHelper.changeSubscription(apiId, newName, new SubscribeHelper.FeedChangedListener() {
@Override
public void done(boolean isError, String apiId) {
if (!isError) {
feeds.getAdapter().notifyDataSetChanged();
Toast.makeText(getContext(), R.string.message_feed_rename_success, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getContext(), R.string.message_feed_rename_error, Toast.LENGTH_SHORT).show();
}
}
});
}
});
editFeedNameDialog.show(getFragmentManager(), "edit_feed");
}
});
feeds.setLayoutManager(new LinearLayoutManager(getContext()));
feeds.setAdapter(adapter);
feeds.setHasFixedSize(true);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
updateData();
}
});
setUpItemTouchHelper(activity, feeds);//connect fancy menu to list items
return view;
}
private void updateData() {
showErrorMessage = true;
userController.downloadContent(); // userController.receiveArticles();
}
@Override
public void onStart() {
super.onStart();
bus.register(this);
}
@Override
public void onStop() {
bus.unregister(this);
super.onStop();
}
@Override
public void onResume() {
super.onResume();
//good idea to update data set here
((FeedsAdapter) feeds.getAdapter()).updateDataSource();
Log.d("TAGS", "Refresh");
}
@Subscribe
public void onShowUnreadStateChanged(ArticleViewPreferenceChanged evt) {
//This method will be called when you click show/hide unread articles
//toggle on the top of the main screen
//adapter should receive it's new filtering politic
((FeedsAdapter) feeds.getAdapter()).setHideEmptyFeeds(evt.isShowUnread());
}
@Subscribe
public void onFeedsReceived(FeedsReceivedEvent evt) {
//When we hav downloaded feeds
((FeedsAdapter) feeds.getAdapter()).updateDataSource();
}
// TODO: 15.01.17 UPDATE ARTICLES CALL should go here!
@Subscribe
public void onArticleModified(ArticleReadedChange event) {
//when you read the article this method is fired
//this method used to update unread articles amount counters in feeds list
feeds.getAdapter().notifyDataSetChanged();
}
@Subscribe
public void updateArticles(UpdateArticle updateArticle) {
if (isAdded()) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
swipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
swipeRefreshLayout.setRefreshing(false);
}
});
feeds.getAdapter().notifyDataSetChanged();
}
});
}
}
@Subscribe
public void updateArticlesError(UpdateArticleFailureEvent failure) {
if (isAdded()) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
if (showErrorMessage) {
Toast.makeText(FeedsArticles.this.getActivity(), R.string.warning_network_error, Toast.LENGTH_SHORT).show();
}
swipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
swipeRefreshLayout.setRefreshing(false);
}
});
}
});
}
}
/**
* This is where that fancy swipe menu is attached to feed list items
*
* @param activity inject activity for context
* @param recycler inject recycler to work with
*/
private void setUpItemTouchHelper(final Activity activity, final RecyclerView recycler) {
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
// we want to cache these and not allocate anything repeatedly in the onChildDraw method
Drawable background;
Drawable xMark;
int xMarkMargin;
boolean initiated;
private void init() {
int bgColor = R.color.colorPrimaryDark;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
background = new ColorDrawable(activity.getResources().getColor(bgColor, null));
} else {
background = new ColorDrawable(activity.getResources().getColor(bgColor));
}
xMark = ContextCompat.getDrawable(activity, R.drawable.ic_action_content_create);
xMark.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
xMarkMargin = (int) activity.getResources().getDimension(R.dimen.ic_clear_margin);
initiated = true;
}
// not important, we don't want drag & drop
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
@Override
public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
return super.getSwipeDirs(recyclerView, viewHolder);
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
int swipedPosition = viewHolder.getAdapterPosition();
FeedsAdapter adapter = (FeedsAdapter) recycler.getAdapter();
//onSwipeMenu(swipedPosition);
adapter.addPendingItem(adapter.getItemApiId(swipedPosition));
adapter.notifyItemChanged(swipedPosition);
}
@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
View itemView = viewHolder.itemView;
// not sure why, but this method get's called for viewholder that are already swiped away
if (viewHolder.getAdapterPosition() == -1) {
// not interested in those
return;
}
if (!initiated) {
init();
}
// draw colored background
background.setBounds(itemView.getRight() + (int) dX, itemView.getTop(), itemView.getRight(), itemView.getBottom());
background.draw(c);
// draw x mark
int itemHeight = itemView.getBottom() - itemView.getTop();
int intrinsicWidth = xMark.getIntrinsicWidth();
int intrinsicHeight = xMark.getIntrinsicWidth();
int xMarkLeft = itemView.getRight() - xMarkMargin - intrinsicWidth;
int xMarkRight = itemView.getRight() - xMarkMargin;
int xMarkTop = itemView.getTop() + (itemHeight - intrinsicHeight) / 2;
int xMarkBottom = xMarkTop + intrinsicHeight;
xMark.setBounds(xMarkLeft, xMarkTop, xMarkRight, xMarkBottom);
xMark.draw(c);
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
};
ItemTouchHelper mItemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
mItemTouchHelper.attachToRecyclerView(recycler);
}//end item touch helper
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment