Use diffutil for accounts fragment

This commit is contained in:
Paul Schaub 2019-08-20 20:14:57 +02:00
parent 4a5ccd879d
commit f7697b9ba8
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
9 changed files with 110 additions and 36 deletions

View file

@ -86,7 +86,7 @@ public class ChatInputFragment extends Fragment implements View.OnClickListener
this.actionListener = (OnChatInputActionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnListFragmentInteractionListener");
+ " must implement OnAccountListItemClickListener");
}
}

View file

@ -13,19 +13,22 @@ import org.mercury_im.messenger.R;
import org.mercury_im.messenger.persistence.model.AccountModel;
public class AccountsActivity extends AppCompatActivity
implements AccountsFragment.OnListFragmentInteractionListener {
implements AccountsFragment.OnAccountListItemClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_accounts);
MercuryImApplication.getApplication().getAppComponent().inject(this);
AccountsFragment accountsFragment = (AccountsFragment) getSupportFragmentManager()
.findFragmentById(R.id.fragment_accounts);
}
@Override
public void onListFragmentInteraction(AccountModel item) {
public void onAccountListItemClick(AccountModel item) {
View dialogView = LayoutInflater.from(this).inflate(R.layout.dialog_account_details, null);
AlertDialog.Builder builder = new AlertDialog.Builder(this)
.setView(dialogView)
.setTitle(item.getJid())

View file

@ -19,12 +19,12 @@ import org.mercury_im.messenger.persistence.model.AccountModel;
/**
* A fragment representing a list of Items.
* <p/>
* Activities containing this fragment MUST implement the {@link OnListFragmentInteractionListener}
* Activities containing this fragment MUST implement the {@link OnAccountListItemClickListener}
* interface.
*/
public class AccountsFragment extends Fragment {
private OnListFragmentInteractionListener mListener;
private OnAccountListItemClickListener onAccountListItemClickListener;
AccountsViewModel viewModel;
@ -63,7 +63,7 @@ public class AccountsFragment extends Fragment {
recyclerView = (RecyclerView) view;
Context context = view.getContext();
recyclerView.setLayoutManager(new LinearLayoutManager(context));
this.adapter = new AccountsRecyclerViewAdapter(viewModel.getAccounts().getValue(), mListener);
this.adapter = new AccountsRecyclerViewAdapter(viewModel.getAccounts().getValue(), onAccountListItemClickListener);
viewModel.getAccounts().observe(this, roomAccountModels -> adapter.setValues(roomAccountModels));
recyclerView.setAdapter(adapter);
}
@ -75,18 +75,18 @@ public class AccountsFragment extends Fragment {
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnListFragmentInteractionListener) {
mListener = (OnListFragmentInteractionListener) context;
if (context instanceof OnAccountListItemClickListener) {
onAccountListItemClickListener = (OnAccountListItemClickListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnListFragmentInteractionListener");
+ " must implement OnAccountListItemClickListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
onAccountListItemClickListener = null;
}
/**
@ -99,8 +99,7 @@ public class AccountsFragment extends Fragment {
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnListFragmentInteractionListener {
// TODO: Update argument type and name
void onListFragmentInteraction(AccountModel item);
public interface OnAccountListItemClickListener {
void onAccountListItemClick(AccountModel item);
}
}

View file

@ -1,7 +1,5 @@
package org.mercury_im.messenger.ui.login;
import androidx.recyclerview.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@ -9,10 +7,14 @@ import android.view.ViewGroup;
import android.widget.Switch;
import android.widget.TextView;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.RecyclerView;
import org.mercury_im.messenger.MercuryImApplication;
import org.mercury_im.messenger.R;
import org.mercury_im.messenger.persistence.model.AccountModel;
import org.mercury_im.messenger.ui.login.AccountsFragment.OnListFragmentInteractionListener;
import org.mercury_im.messenger.ui.login.AccountsFragment.OnAccountListItemClickListener;
import org.mercury_im.messenger.util.AbstractDiffCallback;
import java.util.ArrayList;
import java.util.List;
@ -22,9 +24,9 @@ import de.hdodenhof.circleimageview.CircleImageView;
public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter<AccountsRecyclerViewAdapter.ViewHolder> {
private final List<AccountModel> mValues;
private final OnListFragmentInteractionListener mListener;
private final OnAccountListItemClickListener mListener;
public AccountsRecyclerViewAdapter(List<AccountModel> items, OnListFragmentInteractionListener listener) {
public AccountsRecyclerViewAdapter(List<AccountModel> items, OnAccountListItemClickListener listener) {
mValues = items != null ? items : new ArrayList<>();
mListener = listener;
}
@ -41,26 +43,27 @@ public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter<AccountsRe
AccountModel account = mValues.get(position);
holder.jid.setText(account.getJid());
holder.enabled.setChecked(account.getEnabled());
holder.enabled.setOnCheckedChangeListener((compoundButton, b) -> {
account.setEnabled(b);
});
holder.accountModel = account;
holder.status.setText(account.getState());
holder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != mListener) {
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mListener.onListFragmentInteraction(holder.accountModel);
}
holder.mView.setOnClickListener(v -> {
if (null != mListener) {
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mListener.onAccountListItemClick(holder.accountModel);
}
});
}
public void setValues(List<AccountModel> values) {
this.mValues.clear();
if (values != null) {
mValues.addAll(values);
}
notifyDataSetChanged();
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new AccountsDiffCallback(values, mValues), true);
mValues.clear();
mValues.addAll(values);
diffResult.dispatchUpdatesTo(this);
// notifyDataSetChanged(); TODO: Not needed?
}
@Override
@ -86,4 +89,23 @@ public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter<AccountsRe
status = view.findViewById(R.id.text_account_status);
}
}
public class AccountsDiffCallback extends AbstractDiffCallback<AccountModel> {
public AccountsDiffCallback(List<AccountModel> newItems, List<AccountModel> oldItems) {
super(newItems, oldItems);
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return oldItems.get(oldItemPosition).getId() == newItems.get(newItemPosition).getId();
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
AccountModel oldM = oldItems.get(oldItemPosition);
AccountModel newM = newItems.get(newItemPosition);
return oldM.equals(newM);
}
}
}

View file

@ -0,0 +1,26 @@
package org.mercury_im.messenger.util;
import androidx.recyclerview.widget.DiffUtil;
import java.util.List;
public abstract class AbstractDiffCallback<I> extends DiffUtil.Callback {
protected final List<I> newItems;
protected final List<I> oldItems;
public AbstractDiffCallback(List<I> newItems, List<I> oldItems) {
this.newItems = newItems;
this.oldItems = oldItems;
}
@Override
public int getOldListSize() {
return oldItems.size();
}
@Override
public int getNewListSize() {
return newItems.size();
}
}

View file

@ -1,7 +1,7 @@
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment"
android:id="@+id/fragment_accounts"
android:name="org.mercury_im.messenger.ui.login.AccountsFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"

View file

@ -8,6 +8,7 @@ import androidx.room.PrimaryKey;
import androidx.room.TypeConverters;
import org.jxmpp.jid.EntityBareJid;
import org.mercury_im.messenger.persistence.model.AbstractAccountModel;
import org.mercury_im.messenger.persistence.model.AccountModel;
import org.mercury_im.messenger.persistence.room.type_converter.EntityBareJidConverter;
@ -15,7 +16,7 @@ import static org.mercury_im.messenger.persistence.room.model.RoomAccountModel.K
import static org.mercury_im.messenger.persistence.room.model.RoomAccountModel.TABLE;
@Entity(tableName = TABLE, indices = {@Index(KEY_ID)})
public class RoomAccountModel implements AccountModel {
public class RoomAccountModel extends AbstractAccountModel {
public static final String TABLE = "accounts";
public static final String KEY_ID = "pk_account_id";

View file

@ -0,0 +1,22 @@
package org.mercury_im.messenger.persistence.model;
import java.util.Objects;
public abstract class AbstractAccountModel implements AccountModel {
@Override
public boolean equals(Object other) {
if (other == null) return false;
if (this == other) return true;
if (!(other instanceof AccountModel)) {
return false;
}
AccountModel o = (AccountModel) other;
return o.getId() == getId() &&
Objects.equals(o.getJid(), getJid()) &&
Objects.equals(o.getEnabled(), getEnabled()) &&
Objects.equals(o.getPassword(), getPassword()) &&
Objects.equals(o.getState(), getState());
}
}

View file

@ -64,8 +64,9 @@ public interface AccountModel {
void setEnabled(boolean enabled);
/**
* Return the
* @return
* Return the state of the connection.
*
* @return state
*/
String getState();