Recyclerview beginning

This commit is contained in:
tom79 2017-10-14 14:36:48 +02:00
parent 67bd790a9e
commit 206810c69d
9 changed files with 470 additions and 291 deletions

View File

@ -35,6 +35,7 @@ dependencies {
compile 'com.android.support:design:26.0.2'
compile 'com.android.support:support-v4:26.0.2'
compile 'com.android.support:cardview-v7:26.0.2'
compile 'com.android.support:recyclerview-v7:26.0.2'
compile 'com.loopj.android:android-async-http:1.4.9'
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
compile 'com.evernote:android-job:1.1.11'

View File

@ -21,6 +21,8 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView;
@ -35,6 +37,7 @@ import fr.gouv.etalab.mastodon.asynctasks.RetrieveFeedsAsyncTask;
import fr.gouv.etalab.mastodon.client.APIResponse;
import fr.gouv.etalab.mastodon.client.Entities.Status;
import fr.gouv.etalab.mastodon.drawers.StatusListAdapter;
import fr.gouv.etalab.mastodon.fragments.DisplayStatusFragment;
import fr.gouv.etalab.mastodon.helper.Helper;
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveFeedsInterface;
import mastodon.etalab.gouv.fr.mastodon.R;
@ -93,7 +96,7 @@ public class HashTagActivity extends AppCompatActivity implements OnRetrieveFeed
int behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
final ListView lv_status = (ListView) findViewById(R.id.lv_status);
final RecyclerView lv_status = (RecyclerView) findViewById(R.id.lv_status);
tootsPerPage = sharedpreferences.getInt(Helper.SET_TOOTS_PER_PAGE, 40);
mainLoader = (RelativeLayout) findViewById(R.id.loader);
nextElementLoader = (RelativeLayout) findViewById(R.id.loading_next_status);
@ -123,23 +126,28 @@ public class HashTagActivity extends AppCompatActivity implements OnRetrieveFeed
R.color.colorPrimaryD,
R.color.colorPrimaryDarkD);
}
final LinearLayoutManager mLayoutManager;
mLayoutManager = new LinearLayoutManager(this);
lv_status.setLayoutManager(mLayoutManager);
lv_status.addOnScrollListener(new RecyclerView.OnScrollListener() {
public void onScrolled(RecyclerView recyclerView, int dx, int dy)
{
if(dy > 0){
int visibleItemCount = mLayoutManager.getChildCount();
int totalItemCount = mLayoutManager.getItemCount();
int firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
if(firstVisibleItem + visibleItemCount == totalItemCount ) {
if(!flag_loading ) {
flag_loading = true;
new RetrieveFeedsAsyncTask(getApplicationContext(), RetrieveFeedsAsyncTask.Type.TAG, tag,null, max_id, HashTagActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
lv_status.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if(firstVisibleItem + visibleItemCount == totalItemCount ) {
if(!flag_loading ) {
flag_loading = true;
new RetrieveFeedsAsyncTask(getApplicationContext(), RetrieveFeedsAsyncTask.Type.TAG, tag,null, max_id, HashTagActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
nextElementLoader.setVisibility(View.VISIBLE);
nextElementLoader.setVisibility(View.VISIBLE);
}
} else {
nextElementLoader.setVisibility(View.GONE);
}
} else {
nextElementLoader.setVisibility(View.GONE);
}
}
});
new RetrieveFeedsAsyncTask(getApplicationContext(), RetrieveFeedsAsyncTask.Type.TAG, tag,null, max_id, HashTagActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

View File

@ -25,6 +25,8 @@ import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
@ -77,7 +79,7 @@ public class ShowConversationActivity extends AppCompatActivity implements OnRet
private Status initialStatus;
public static int position;
private SwipeRefreshLayout swipeRefreshLayout;
private ListView lv_status;
private RecyclerView lv_status;
private boolean isRefreshed;
private TextView title;
private ImageView pp_actionBar;
@ -179,13 +181,18 @@ public class ShowConversationActivity extends AppCompatActivity implements OnRet
new RetrieveFeedsAsyncTask(getApplicationContext(), RetrieveFeedsAsyncTask.Type.ONESTATUS, statusId,null, false,false, ShowConversationActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
});
lv_status = (ListView) findViewById(R.id.lv_status);
lv_status = (RecyclerView) findViewById(R.id.lv_status);
final LinearLayoutManager mLayoutManager;
mLayoutManager = new LinearLayoutManager(this);
lv_status.setLayoutManager(mLayoutManager);
lv_status.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == android.view.MotionEvent.ACTION_UP) {
if (lv_status.getLastVisiblePosition() == lv_status.getAdapter().getCount() -1 && lv_status.getFirstVisiblePosition() > 0 &&
int visibleItemCount = mLayoutManager.getChildCount();
int totalItemCount = mLayoutManager.getItemCount();
int firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
if (firstVisibleItem + visibleItemCount == lv_status.getAdapter().getItemCount() -1 && firstVisibleItem > 0 &&
lv_status.getChildAt(lv_status.getChildCount() - 1).getBottom() <= lv_status.getHeight()) {
swipeRefreshLayout.setRefreshing(true);
@ -267,7 +274,7 @@ public class ShowConversationActivity extends AppCompatActivity implements OnRet
lv_status.setVisibility(View.VISIBLE);
if( isRefreshed){
position = statuses.size()-1;
lv_status.setSelection(position);
lv_status.scrollToPosition(position);
}else {
lv_status.smoothScrollToPosition(position);
}

View File

@ -34,6 +34,7 @@ import android.os.CountDownTimer;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.CardView;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.RecyclerView;
import android.text.Html;
import android.text.SpannableString;
import android.text.method.LinkMovementMethod;
@ -45,7 +46,6 @@ import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
@ -105,14 +105,13 @@ import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor;
* Created by Thomas on 24/04/2017.
* Adapter for Status
*/
public class StatusListAdapter extends BaseAdapter implements OnPostActionInterface, OnTranslatedInterface, OnRetrieveFeedsInterface {
public class StatusListAdapter extends RecyclerView.Adapter implements OnPostActionInterface, OnTranslatedInterface, OnRetrieveFeedsInterface {
private Context context;
private List<Status> statuses;
private LayoutInflater layoutInflater;
private ImageLoader imageLoader;
private DisplayImageOptions options;
private ViewHolder holder;
private boolean isOnWifi;
private int translator;
private int behaviorWithAttachments;
@ -126,6 +125,7 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
private List<Status> pins;
public StatusListAdapter(Context context, RetrieveFeedsAsyncTask.Type type, String targetedId, boolean isOnWifi, int behaviorWithAttachments, int translator, List<Status> statuses){
super();
this.context = context;
this.statuses = statuses;
this.isOnWifi = isOnWifi;
@ -140,24 +140,117 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
@Override
public int getCount() {
return statuses.size();
}
@Override
public Object getItem(int position) {
return statuses.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getViewTypeCount() {
return 2;
public int getItemCount() {
return statuses.size();
}
private class ViewHolderEmpty extends RecyclerView.ViewHolder{
ViewHolderEmpty(View itemView) {
super(itemView);
}
}
class ViewHolder extends RecyclerView.ViewHolder{
LinearLayout status_content_container;
LinearLayout status_spoiler_container;
TextView status_spoiler;
Button status_spoiler_button;
CardView card_status_container;
TextView status_content;
TextView status_content_translated;
LinearLayout status_content_translated_container;
TextView status_account_username;
TextView status_account_displayname;
ImageView status_account_profile;
ImageView status_account_profile_boost;
ImageView status_account_profile_boost_by;
TextView status_favorite_count;
TextView status_reblog_count;
TextView status_toot_date;
TextView status_reblog_user;
Button status_show_more;
ImageView status_more;
LinearLayout status_document_container;
ImageView status_prev1;
ImageView status_prev2;
ImageView status_prev3;
ImageView status_prev4;
ImageView status_prev1_play;
ImageView status_prev2_play;
ImageView status_prev3_play;
ImageView status_prev4_play;
RelativeLayout status_prev4_container;
ImageView status_reply;
ImageView status_pin;
ImageView status_privacy;
FloatingActionButton status_translate;
LinearLayout status_container2;
LinearLayout status_container3;
LinearLayout main_container;
TextView yandex_translate;
TextView google_translate;
LinearLayout status_action_container;
LinearLayout status_replies;
LinearLayout status_replies_profile_pictures;
TextView status_replies_text;
LinearLayout loader_replies;
ImageView new_element;
ViewHolder(View itemView) {
super(itemView);
loader_replies = itemView.findViewById(R.id.loader_replies);
card_status_container = itemView.findViewById(R.id.card_status_container);
status_document_container = (LinearLayout) itemView.findViewById(R.id.status_document_container);
status_content = (TextView) itemView.findViewById(R.id.status_content);
status_content_translated = (TextView) itemView.findViewById(R.id.status_content_translated);
status_account_username = (TextView) itemView.findViewById(R.id.status_account_username);
status_account_displayname = (TextView) itemView.findViewById(R.id.status_account_displayname);
status_account_profile = (ImageView) itemView.findViewById(R.id.status_account_profile);
status_account_profile_boost = (ImageView) itemView.findViewById(R.id.status_account_profile_boost);
status_account_profile_boost_by = (ImageView) itemView.findViewById(R.id.status_account_profile_boost_by);
status_favorite_count = (TextView) itemView.findViewById(R.id.status_favorite_count);
status_reblog_count = (TextView) itemView.findViewById(R.id.status_reblog_count);
status_pin = (ImageView) itemView.findViewById(R.id.status_pin);
status_toot_date = (TextView) itemView.findViewById(R.id.status_toot_date);
status_show_more = (Button) itemView.findViewById(R.id.status_show_more);
status_more = (ImageView) itemView.findViewById(R.id.status_more);
status_reblog_user = (TextView) itemView.findViewById(R.id.status_reblog_user);
status_prev1 = (ImageView) itemView.findViewById(R.id.status_prev1);
status_prev2 = (ImageView) itemView.findViewById(R.id.status_prev2);
status_prev3 = (ImageView) itemView.findViewById(R.id.status_prev3);
status_prev4 = (ImageView) itemView.findViewById(R.id.status_prev4);
status_prev1_play = (ImageView) itemView.findViewById(R.id.status_prev1_play);
status_prev2_play = (ImageView) itemView.findViewById(R.id.status_prev2_play);
status_prev3_play = (ImageView) itemView.findViewById(R.id.status_prev3_play);
status_prev4_play = (ImageView) itemView.findViewById(R.id.status_prev4_play);
status_container2 = (LinearLayout) itemView.findViewById(R.id.status_container2);
status_container3 = (LinearLayout) itemView.findViewById(R.id.status_container3);
status_prev4_container = (RelativeLayout) itemView.findViewById(R.id.status_prev4_container);
status_reply = (ImageView) itemView.findViewById(R.id.status_reply);
status_privacy = (ImageView) itemView.findViewById(R.id.status_privacy);
status_translate = (FloatingActionButton) itemView.findViewById(R.id.status_translate);
status_content_translated_container = (LinearLayout) itemView.findViewById(R.id.status_content_translated_container);
main_container = (LinearLayout) itemView.findViewById(R.id.main_container);
status_spoiler_container = (LinearLayout) itemView.findViewById(R.id.status_spoiler_container);
status_content_container = (LinearLayout) itemView.findViewById(R.id.status_content_container);
status_spoiler = (TextView) itemView.findViewById(R.id.status_spoiler);
status_spoiler_button = (Button) itemView.findViewById(R.id.status_spoiler_button);
yandex_translate = (TextView) itemView.findViewById(R.id.yandex_translate);
google_translate = (TextView) itemView.findViewById(R.id.google_translate);
status_replies = (LinearLayout) itemView.findViewById(R.id.status_replies);
status_replies_profile_pictures = (LinearLayout) itemView.findViewById(R.id.status_replies_profile_pictures);
status_replies_text = (TextView) itemView.findViewById(R.id.status_replies_text);
new_element = (ImageView) itemView.findViewById(R.id.new_element);
status_action_container = (LinearLayout) itemView.findViewById(R.id.status_action_container);
}
}
@Override
@ -175,13 +268,23 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
return DISPLAYED_STATUS;
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if( viewType == DISPLAYED_STATUS)
return new ViewHolder(layoutInflater.inflate(R.layout.drawer_status, parent, false));
else
return new ViewHolderEmpty(layoutInflater.inflate(R.layout.drawer_status, parent, false));
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, final int position) {
if( viewHolder.getItemViewType() == HIDDEN_STATUS){
if( getItemViewType(position) == HIDDEN_STATUS){
return new View(context);
}else {
final ViewHolder holder = (ViewHolder) viewHolder;
holder.card_status_container.setVisibility(View.VISIBLE);
final Status status = statuses.get(position);
imageLoader = ImageLoader.getInstance();
File cacheDir = new File(context.getCacheDir(), context.getString(R.string.app_name));
@ -197,57 +300,6 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
options = new DisplayImageOptions.Builder().displayer(new SimpleBitmapDisplayer()).cacheInMemory(false)
.cacheOnDisk(true).resetViewBeforeLoading(true).build();
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.drawer_status, parent, false);
holder = new ViewHolder();
holder.loader_replies = (LinearLayout) convertView.findViewById(R.id.loader_replies);
holder.card_status_container = (CardView) convertView.findViewById(R.id.card_status_container);
holder.status_document_container = (LinearLayout) convertView.findViewById(R.id.status_document_container);
holder.status_content = (TextView) convertView.findViewById(R.id.status_content);
holder.status_content_translated = (TextView) convertView.findViewById(R.id.status_content_translated);
holder.status_account_username = (TextView) convertView.findViewById(R.id.status_account_username);
holder.status_account_displayname = (TextView) convertView.findViewById(R.id.status_account_displayname);
holder.status_account_profile = (ImageView) convertView.findViewById(R.id.status_account_profile);
holder.status_account_profile_boost = (ImageView) convertView.findViewById(R.id.status_account_profile_boost);
holder.status_account_profile_boost_by = (ImageView) convertView.findViewById(R.id.status_account_profile_boost_by);
holder.status_favorite_count = (TextView) convertView.findViewById(R.id.status_favorite_count);
holder.status_reblog_count = (TextView) convertView.findViewById(R.id.status_reblog_count);
holder.status_pin = (ImageView) convertView.findViewById(R.id.status_pin);
holder.status_toot_date = (TextView) convertView.findViewById(R.id.status_toot_date);
holder.status_show_more = (Button) convertView.findViewById(R.id.status_show_more);
holder.status_more = (ImageView) convertView.findViewById(R.id.status_more);
holder.status_reblog_user = (TextView) convertView.findViewById(R.id.status_reblog_user);
holder.status_prev1 = (ImageView) convertView.findViewById(R.id.status_prev1);
holder.status_prev2 = (ImageView) convertView.findViewById(R.id.status_prev2);
holder.status_prev3 = (ImageView) convertView.findViewById(R.id.status_prev3);
holder.status_prev4 = (ImageView) convertView.findViewById(R.id.status_prev4);
holder.status_prev1_play = (ImageView) convertView.findViewById(R.id.status_prev1_play);
holder.status_prev2_play = (ImageView) convertView.findViewById(R.id.status_prev2_play);
holder.status_prev3_play = (ImageView) convertView.findViewById(R.id.status_prev3_play);
holder.status_prev4_play = (ImageView) convertView.findViewById(R.id.status_prev4_play);
holder.status_container2 = (LinearLayout) convertView.findViewById(R.id.status_container2);
holder.status_container3 = (LinearLayout) convertView.findViewById(R.id.status_container3);
holder.status_prev4_container = (RelativeLayout) convertView.findViewById(R.id.status_prev4_container);
holder.status_reply = (ImageView) convertView.findViewById(R.id.status_reply);
holder.status_privacy = (ImageView) convertView.findViewById(R.id.status_privacy);
holder.status_translate = (FloatingActionButton) convertView.findViewById(R.id.status_translate);
holder.status_content_translated_container = (LinearLayout) convertView.findViewById(R.id.status_content_translated_container);
holder.main_container = (LinearLayout) convertView.findViewById(R.id.main_container);
holder.status_spoiler_container = (LinearLayout) convertView.findViewById(R.id.status_spoiler_container);
holder.status_content_container = (LinearLayout) convertView.findViewById(R.id.status_content_container);
holder.status_spoiler = (TextView) convertView.findViewById(R.id.status_spoiler);
holder.status_spoiler_button = (Button) convertView.findViewById(R.id.status_spoiler_button);
holder.yandex_translate = (TextView) convertView.findViewById(R.id.yandex_translate);
holder.google_translate = (TextView) convertView.findViewById(R.id.google_translate);
holder.status_replies = (LinearLayout) convertView.findViewById(R.id.status_replies);
holder.status_replies_profile_pictures = (LinearLayout) convertView.findViewById(R.id.status_replies_profile_pictures);
holder.status_replies_text = (TextView) convertView.findViewById(R.id.status_replies_text);
holder.new_element = (ImageView) convertView.findViewById(R.id.new_element);
holder.status_action_container = (LinearLayout) convertView.findViewById(R.id.status_action_container);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
@ -902,7 +954,6 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
final View finalConvertView = convertView;
final View attached = holder.status_more;
holder.status_more.setOnClickListener(new View.OnClickListener() {
@Override
@ -986,7 +1037,7 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
@Override
public void run() {
Bitmap bitmap = Helper.convertTootIntoBitmap(context, finalConvertView);
Bitmap bitmap = Helper.convertTootIntoBitmap(context, holder.card_status_container);
status.setTakingScreenShot(false);
statusListAdapter.notifyDataSetChanged();
Intent intent = new Intent(context, TootActivity.class);
@ -1086,14 +1137,17 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
}
}
});
return convertView;
}
}
private void loadAttachments(final Status status, ViewHolder holder){
private void loadAttachments(final Status status, RecyclerView.ViewHolder viewHolder){
final ViewHolder holder = (ViewHolder) viewHolder;
List<Attachment> attachments = status.getMedia_attachments();
if( attachments != null && attachments.size() > 0){
int i = 0;
@ -1379,53 +1433,7 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
}
private class ViewHolder {
LinearLayout status_content_container;
LinearLayout status_spoiler_container;
TextView status_spoiler;
Button status_spoiler_button;
CardView card_status_container;
TextView status_content;
TextView status_content_translated;
LinearLayout status_content_translated_container;
TextView status_account_username;
TextView status_account_displayname;
ImageView status_account_profile;
ImageView status_account_profile_boost;
ImageView status_account_profile_boost_by;
TextView status_favorite_count;
TextView status_reblog_count;
TextView status_toot_date;
TextView status_reblog_user;
Button status_show_more;
ImageView status_more;
LinearLayout status_document_container;
ImageView status_prev1;
ImageView status_prev2;
ImageView status_prev3;
ImageView status_prev4;
ImageView status_prev1_play;
ImageView status_prev2_play;
ImageView status_prev3_play;
ImageView status_prev4_play;
RelativeLayout status_prev4_container;
ImageView status_reply;
ImageView status_pin;
ImageView status_privacy;
FloatingActionButton status_translate;
LinearLayout status_container2;
LinearLayout status_container3;
LinearLayout main_container;
TextView yandex_translate;
TextView google_translate;
LinearLayout status_action_container;
LinearLayout status_replies;
LinearLayout status_replies_profile_pictures;
TextView status_replies_text;
LinearLayout loader_replies;
ImageView new_element;
}

View File

@ -25,6 +25,8 @@ import android.support.v4.app.Fragment;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@ -75,7 +77,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
private String targetedId;
private String tag;
private boolean swiped;
private ListView lv_status;
private RecyclerView lv_status;
private boolean isOnWifi;
private int behaviorWithAttachments;
private boolean showMediaOnly, showPinned;
@ -128,7 +130,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
if( type == RetrieveFeedsAsyncTask.Type.HOME)
lastReadStatus = sharedpreferences.getString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, null);
lv_status = (ListView) rootView.findViewById(R.id.lv_status);
lv_status = (RecyclerView) rootView.findViewById(R.id.lv_status);
mainLoader = (RelativeLayout) rootView.findViewById(R.id.loader);
nextElementLoader = (RelativeLayout) rootView.findViewById(R.id.loading_next_status);
textviewNoAction = (RelativeLayout) rootView.findViewById(R.id.no_action);
@ -142,47 +144,34 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
if (hideHeader && Build.VERSION.SDK_INT >= 21)
ViewCompat.setNestedScrollingEnabled(lv_status, true);
lv_status.setOnScrollListener(new AbsListView.OnScrollListener() {
int lastFirstVisibleItem = 0;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
final LinearLayoutManager mLayoutManager;
mLayoutManager = new LinearLayoutManager(context);
lv_status.setLayoutManager(mLayoutManager);
}
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (hideHeader && Build.VERSION.SDK_INT < 21) {
if(firstVisibleItem == 0 && Helper.listIsAtTop(lv_status)){
Intent intent = new Intent(Helper.HEADER_ACCOUNT+instanceValue);
intent.putExtra("hide", false);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}else if (view.getId() == lv_status.getId() && totalItemCount > visibleItemCount) {
final int currentFirstVisibleItem = lv_status.getFirstVisiblePosition();
if (currentFirstVisibleItem > lastFirstVisibleItem) {
Intent intent = new Intent(Helper.HEADER_ACCOUNT + instanceValue);
intent.putExtra("hide", true);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
} else if (currentFirstVisibleItem < lastFirstVisibleItem) {
Intent intent = new Intent(Helper.HEADER_ACCOUNT + instanceValue);
intent.putExtra("hide", false);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
lv_status.addOnScrollListener(new RecyclerView.OnScrollListener() {
public void onScrolled(RecyclerView recyclerView, int dx, int dy)
{
if(dy > 0){
int visibleItemCount = mLayoutManager.getChildCount();
int totalItemCount = mLayoutManager.getItemCount();
int firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
if(firstVisibleItem + visibleItemCount == totalItemCount ) {
if(!flag_loading ) {
flag_loading = true;
if( type == RetrieveFeedsAsyncTask.Type.USER)
asyncTask = new RetrieveFeedsAsyncTask(context, type, targetedId, max_id, showMediaOnly, showPinned, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else if( type == RetrieveFeedsAsyncTask.Type.TAG)
asyncTask = new RetrieveFeedsAsyncTask(context, type, tag, targetedId, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else
asyncTask = new RetrieveFeedsAsyncTask(context, type, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
nextElementLoader.setVisibility(View.VISIBLE);
}
lastFirstVisibleItem = currentFirstVisibleItem;
} else {
nextElementLoader.setVisibility(View.GONE);
}
}
if(firstVisibleItem + visibleItemCount == totalItemCount ) {
if(!flag_loading ) {
flag_loading = true;
if( type == RetrieveFeedsAsyncTask.Type.USER)
asyncTask = new RetrieveFeedsAsyncTask(context, type, targetedId, max_id, showMediaOnly, showPinned, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else if( type == RetrieveFeedsAsyncTask.Type.TAG)
asyncTask = new RetrieveFeedsAsyncTask(context, type, tag, targetedId, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else
asyncTask = new RetrieveFeedsAsyncTask(context, type, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
nextElementLoader.setVisibility(View.VISIBLE);
}
} else {
nextElementLoader.setVisibility(View.GONE);
}
}
});
@ -336,9 +325,6 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
if (status != null) {
//Update the id of the last toot retrieved
MainActivity.lastHomeId = status.getId();
int index = lv_status.getFirstVisiblePosition() + 1;
View v = lv_status.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();
status.setReplies(new ArrayList<Status>());
statuses.add(0,status);
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
@ -346,7 +332,6 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
if( !status.getAccount().getId().equals(userId))
MainActivity.countNewStatus++;
statusListAdapter.notifyDataSetChanged();
lv_status.setSelectionFromTop(index, top);
if (textviewNoAction.getVisibility() == View.VISIBLE)
textviewNoAction.setVisibility(View.GONE);
}
@ -355,15 +340,8 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
return;
//Avoids the array to be too big...
if (status != null) {
if (lv_status.getFirstVisiblePosition() == 0) {
status.setReplies(new ArrayList<Status>());
status.setNew(false);
statuses.add(0, status);
statusListAdapter.notifyDataSetChanged();
} else {
status.setReplies(new ArrayList<Status>());
statuses.add(0, status);
}
status.setReplies(new ArrayList<Status>());
statuses.add(0, status);
if (textviewNoAction.getVisibility() == View.VISIBLE)
textviewNoAction.setVisibility(View.GONE);
}
@ -374,11 +352,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
* Refresh status in list
*/
public void refreshFilter(){
int index = lv_status.getFirstVisiblePosition() + 1;
View v = lv_status.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();
statusListAdapter.notifyDataSetChanged();
lv_status.setSelectionFromTop(index, top);
}
@Override
@ -543,39 +517,19 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
for (Status st : this.statuses) {
knownId.add(st.getId());
}
if( lv_status.getFirstVisiblePosition() > 1 ) {
int index = lv_status.getFirstVisiblePosition() + statuses.size();
View v = lv_status.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();
for (int i = statuses.size() - 1; i >= 0; i--) {
if (!knownId.contains(statuses.get(i).getId())) {
if (type == RetrieveFeedsAsyncTask.Type.HOME)
statuses.get(i).setNew(true);
statuses.get(i).setReplies(new ArrayList<Status>());
this.statuses.add(0, statuses.get(i));
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
if (type == RetrieveFeedsAsyncTask.Type.HOME && !statuses.get(i).getAccount().getId().equals(userId))
MainActivity.countNewStatus++;
}
for (int i = statuses.size() - 1; i >= 0; i--) {
if (!knownId.contains(statuses.get(i).getId())) {
if (type == RetrieveFeedsAsyncTask.Type.HOME)
statuses.get(i).setNew(true);
statuses.get(i).setReplies(new ArrayList<Status>());
this.statuses.add(0, statuses.get(i));
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
if (type == RetrieveFeedsAsyncTask.Type.HOME && !statuses.get(i).getAccount().getId().equals(userId))
MainActivity.countNewStatus++;
}
statusListAdapter.notifyDataSetChanged();
lv_status.setSelectionFromTop(index, top);
}else {
for (int i = statuses.size() - 1; i >= 0; i--) {
if (!knownId.contains(statuses.get(i).getId())) {
if (type == RetrieveFeedsAsyncTask.Type.HOME)
statuses.get(i).setNew(true);
statuses.get(i).setReplies(new ArrayList<Status>());
this.statuses.add(0, statuses.get(i));
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
if (type == RetrieveFeedsAsyncTask.Type.HOME && !statuses.get(i).getAccount().getId().equals(userId))
MainActivity.countNewStatus++;
}
}
statusListAdapter.notifyDataSetChanged();
}
statusListAdapter.notifyDataSetChanged();
try {
((MainActivity) context).updateHomeCounter();
}catch (Exception ignored){}

View File

@ -24,6 +24,7 @@ import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.RecyclerView;
import android.text.Html;
import android.util.Log;
import android.widget.BaseAdapter;
@ -117,67 +118,6 @@ public class CrossActions {
}
}
public static void doCrossReply(final Context context, final Status status, final RetrieveFeedsAsyncTask.Type type, boolean limitedToOwner){
List<Account> accounts = connectedAccounts(context, status, limitedToOwner);
if( accounts.size() == 1) {
Intent intent = new Intent(context, TootActivity.class);
Bundle b = new Bundle();
if( status.getReblog() != null )
b.putParcelable("tootReply", status.getReblog());
else
b.putParcelable("tootReply", status);
intent.putExtras(b); //Put your id to your next Intent
context.startActivity(intent);
if( type == RetrieveFeedsAsyncTask.Type.CONTEXT ){
try {
//Avoid to open multi activities when replying in a conversation
((ShowConversationActivity)context).finish();
}catch (Exception ignored){}
}
}else {
AlertDialog.Builder builderSingle = new AlertDialog.Builder(context);
builderSingle.setTitle(context.getString(R.string.choose_accounts));
final AccountsSearchAdapter accountsSearchAdapter = new AccountsSearchAdapter(context, accounts, true);
final Account[] accountArray = new Account[accounts.size()];
int i = 0;
for(Account account: accounts){
accountArray[i] = account;
i++;
}
builderSingle.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builderSingle.setAdapter(accountsSearchAdapter, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Account account = accountArray[which];
Intent intent = new Intent(context, TootActivity.class);
Bundle b = new Bundle();
if( status.getReblog() != null )
b.putParcelable("tootReply", status.getReblog());
else
b.putParcelable("tootReply", status);
b.putParcelable("accountReply", account);
intent.putExtras(b); //Put your id to your next Intent
context.startActivity(intent);
if( type == RetrieveFeedsAsyncTask.Type.CONTEXT ){
try {
//Avoid to open multi activities when replying in a conversation
((ShowConversationActivity)context).finish();
}catch (Exception ignored){}
}
dialog.dismiss();
}
});
builderSingle.show();
}
}
/**
@ -335,4 +275,256 @@ public class CrossActions {
}
public static void doCrossAction(final Context context, final Status status, final API.StatusAction doAction, final RecyclerView.Adapter baseAdapter, final OnPostActionInterface onPostActionInterface, boolean limitedToOwner){
List<Account> accounts = connectedAccounts(context, status, limitedToOwner);
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
boolean undoAction = (doAction == API.StatusAction.UNPIN || doAction == API.StatusAction.UNREBLOG || doAction == API.StatusAction.UNFAVOURITE );
//Undo actions won't ask for choosing a user
if( accounts.size() == 1 || undoAction ) {
boolean confirmation = false;
if( doAction == API.StatusAction.UNFAVOURITE || doAction == API.StatusAction.FAVOURITE)
confirmation = sharedpreferences.getBoolean(Helper.SET_NOTIF_VALIDATION_FAV, false);
else if( doAction == API.StatusAction.UNREBLOG || doAction == API.StatusAction.REBLOG )
confirmation = sharedpreferences.getBoolean(Helper.SET_NOTIF_VALIDATION, true);
if (confirmation)
displayConfirmationDialog(context, doAction, status, baseAdapter, onPostActionInterface);
else {
if( doAction == API.StatusAction.REBLOG || doAction == API.StatusAction.UNREBLOG)
reblogAction(context, status, baseAdapter, onPostActionInterface);
else if( doAction == API.StatusAction.FAVOURITE || doAction == API.StatusAction.UNFAVOURITE)
favouriteAction(context, status, baseAdapter, onPostActionInterface);
else if ( doAction == API.StatusAction.PIN || doAction == API.StatusAction.UNPIN)
pinAction(context, status, baseAdapter, onPostActionInterface);
}
}else {
AlertDialog.Builder builderSingle = new AlertDialog.Builder(context);
builderSingle.setTitle(context.getString(R.string.choose_accounts));
final AccountsSearchAdapter accountsSearchAdapter = new AccountsSearchAdapter(context, accounts, true);
final Account[] accountArray = new Account[accounts.size()];
int i = 0;
for(Account account: accounts){
accountArray[i] = account;
i++;
}
builderSingle.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builderSingle.setAdapter(accountsSearchAdapter, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Account selectedAccount = accountArray[which];
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
Account loggedAccount = new AccountDAO(context, db).getAccountByID(userId);
if(loggedAccount.getInstance().equals(selectedAccount.getInstance())){
new PostActionAsyncTask(context, selectedAccount, doAction, status.getId(), onPostActionInterface).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}else{ //Account is from another instance
new PostActionAsyncTask(context, selectedAccount, status, doAction, onPostActionInterface).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
if( selectedAccount.getInstance().equals(loggedAccount.getInstance()) && selectedAccount.getId().equals(loggedAccount.getId())) {
if (doAction == API.StatusAction.REBLOG) {
status.setReblogged(true);
} else if (doAction == API.StatusAction.FAVOURITE) {
status.setFavourited(true);
} else if (doAction == API.StatusAction.PIN) {
status.setPinned(true);
}
baseAdapter.notifyDataSetChanged();
}
dialog.dismiss();
}
});
builderSingle.show();
}
}
public static void doCrossReply(final Context context, final Status status, final RetrieveFeedsAsyncTask.Type type, boolean limitedToOwner){
List<Account> accounts = connectedAccounts(context, status, limitedToOwner);
if( accounts.size() == 1) {
Intent intent = new Intent(context, TootActivity.class);
Bundle b = new Bundle();
if( status.getReblog() != null )
b.putParcelable("tootReply", status.getReblog());
else
b.putParcelable("tootReply", status);
intent.putExtras(b); //Put your id to your next Intent
context.startActivity(intent);
if( type == RetrieveFeedsAsyncTask.Type.CONTEXT ){
try {
//Avoid to open multi activities when replying in a conversation
((ShowConversationActivity)context).finish();
}catch (Exception ignored){}
}
}else {
AlertDialog.Builder builderSingle = new AlertDialog.Builder(context);
builderSingle.setTitle(context.getString(R.string.choose_accounts));
final AccountsSearchAdapter accountsSearchAdapter = new AccountsSearchAdapter(context, accounts, true);
final Account[] accountArray = new Account[accounts.size()];
int i = 0;
for(Account account: accounts){
accountArray[i] = account;
i++;
}
builderSingle.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builderSingle.setAdapter(accountsSearchAdapter, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Account account = accountArray[which];
Intent intent = new Intent(context, TootActivity.class);
Bundle b = new Bundle();
if( status.getReblog() != null )
b.putParcelable("tootReply", status.getReblog());
else
b.putParcelable("tootReply", status);
b.putParcelable("accountReply", account);
intent.putExtras(b); //Put your id to your next Intent
context.startActivity(intent);
if( type == RetrieveFeedsAsyncTask.Type.CONTEXT ){
try {
//Avoid to open multi activities when replying in a conversation
((ShowConversationActivity)context).finish();
}catch (Exception ignored){}
}
dialog.dismiss();
}
});
builderSingle.show();
}
}
/**
* Display a validation message
* @param action int
* @param status Status
*/
private static void displayConfirmationDialog(final Context context, final API.StatusAction action, final Status status, final RecyclerView.Adapter baseAdapter, final OnPostActionInterface onPostActionInterface){
String title = null;
if( action == API.StatusAction.FAVOURITE){
title = context.getString(R.string.favourite_add);
}else if( action == API.StatusAction.UNFAVOURITE){
title = context.getString(R.string.favourite_remove);
}else if( action == API.StatusAction.REBLOG){
title = context.getString(R.string.reblog_add);
}else if(action == API.StatusAction.UNREBLOG){
title = context.getString(R.string.reblog_remove);
}else if ( action == API.StatusAction.PIN) {
title = context.getString(R.string.pin_add);
}else if (action == API.StatusAction.UNPIN) {
title = context.getString(R.string.pin_remove);
}
AlertDialog.Builder builder = new AlertDialog.Builder(context);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
builder.setMessage(Html.fromHtml(status.getContent(), Html.FROM_HTML_MODE_LEGACY));
else
//noinspection deprecation
builder.setMessage(Html.fromHtml(status.getContent()));
builder.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle(title)
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if( action == API.StatusAction.REBLOG || action == API.StatusAction.UNREBLOG)
reblogAction(context, status, baseAdapter, onPostActionInterface);
else if( action == API.StatusAction.FAVOURITE || action == API.StatusAction.UNFAVOURITE)
favouriteAction(context, status, baseAdapter, onPostActionInterface);
else if ( action == API.StatusAction.PIN || action == API.StatusAction.UNPIN)
pinAction(context, status, baseAdapter, onPostActionInterface);
dialog.dismiss();
}
})
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.show();
}
/**
* Favourites/Unfavourites a status
* @param status Status
*/
private static void favouriteAction(Context context, Status status, RecyclerView.Adapter baseAdapter, OnPostActionInterface onPostActionInterface){
if( status.isFavourited() || (status.getReblog() != null && status.getReblog().isFavourited())){
new PostActionAsyncTask(context, API.StatusAction.UNFAVOURITE, status.getId(), onPostActionInterface).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
status.setFavourited(false);
}else{
new PostActionAsyncTask(context, API.StatusAction.FAVOURITE, status.getId(), onPostActionInterface).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
status.setFavourited(true);
}
baseAdapter.notifyDataSetChanged();
}
/**
* Reblog/Unreblog a status
* @param status Status
*/
private static void reblogAction(Context context, Status status, RecyclerView.Adapter baseAdapter, OnPostActionInterface onPostActionInterface){
if( status.isReblogged() || (status.getReblog()!= null && status.getReblog().isReblogged())){
String statusId = status.getReblog()!=null?status.getReblog().getId():status.getId();
new PostActionAsyncTask(context, API.StatusAction.UNREBLOG, statusId, onPostActionInterface).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
status.setReblogged(false);
}else{
new PostActionAsyncTask(context, API.StatusAction.REBLOG, status.getId(), onPostActionInterface).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
status.setReblogged(true);
}
baseAdapter.notifyDataSetChanged();
}
/**
* Pin or unpin a status
* @param status Status
*/
private static void pinAction(Context context, Status status, RecyclerView.Adapter baseAdapter, OnPostActionInterface onPostActionInterface) {
if (status.isPinned()) {
new PostActionAsyncTask(context, API.StatusAction.UNPIN, status.getId(), onPostActionInterface).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
status.setPinned(false);
} else {
new PostActionAsyncTask(context, API.StatusAction.PIN, status.getId(), onPostActionInterface).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
status.setPinned(true);
}
baseAdapter.notifyDataSetChanged();
}
}

View File

@ -58,6 +58,7 @@ import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.text.Html;
import android.text.SpannableString;
@ -1527,6 +1528,15 @@ public class Helper {
}
}
/**
* Returns true if a ListView is at its top position
* @param listView ListView
* @return boolean
*/
public static boolean listIsAtTop(RecyclerView listView) {
return listView.getChildCount() == 0 || listView.getChildAt(0).getTop() == 0;
}
/**
* Returns true if a ListView is at its top position
* @param listView ListView

View File

@ -27,14 +27,13 @@
android:layout_width="match_parent"
android:id="@+id/swipeContainer"
android:layout_height="match_parent">
<ListView
<android.support.v7.widget.RecyclerView
android:id="@+id/lv_accounts"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none"
android:divider="@null"
>
</ListView>
/>
</android.support.v4.widget.SwipeRefreshLayout>
<RelativeLayout
android:id="@+id/no_action"

View File

@ -27,7 +27,7 @@
android:layout_width="match_parent"
android:id="@+id/swipeContainer"
android:layout_height="match_parent">
<ListView
<android.support.v7.widget.RecyclerView
android:id="@+id/lv_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"