Android - First list of friends implementation in List of Friends

This commit is contained in:
Cristian Luis Duarte 2018-06-14 15:19:21 -03:00
parent 440ba7a6de
commit 248be87fa3
6 changed files with 296 additions and 1 deletions

View file

@ -3,12 +3,15 @@ package io.highfidelity.hifiinterface.fragment;
import android.app.Fragment;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import io.highfidelity.hifiinterface.R;
import io.highfidelity.hifiinterface.view.UserListAdapter;
public class FriendsFragment extends Fragment {
@ -16,6 +19,9 @@ public class FriendsFragment extends Fragment {
public native String nativeGetAccessToken();
private RecyclerView mUsersView;
private UserListAdapter mUsersAdapter;
public FriendsFragment() {
// Required empty public constructor
}
@ -32,7 +38,14 @@ public class FriendsFragment extends Fragment {
String accessToken = nativeGetAccessToken();
Log.d("[TOKENX]", "token : [" + accessToken + "]");
Log.d("[USERS]", "token : [" + accessToken + "]");
mUsersView = rootView.findViewById(R.id.rvUsers);
int numberOfColumns = 1;
GridLayoutManager gridLayoutMgr = new GridLayoutManager(getContext(), numberOfColumns);
mUsersView.setLayoutManager(gridLayoutMgr);
mUsersAdapter = new UserListAdapter(getContext(), accessToken);
mUsersView.setAdapter(mUsersAdapter);
return rootView;
}

View file

@ -0,0 +1,130 @@
package io.highfidelity.hifiinterface.provider;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import io.highfidelity.hifiinterface.view.UserListAdapter;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.GET;
import retrofit2.http.Query;
/**
* Created by cduarte on 6/13/18.
*/
public class EndpointUsersProvider implements UsersProvider {
public static final String BASE_URL = "https://metaverse.highfidelity.com/";
private final Retrofit mRetrofit;
private final EndpointUsersProviderService mEndpointUsersProviderService;
public EndpointUsersProvider(String accessToken) {
mRetrofit = createAuthorizedRetrofit(accessToken);
mEndpointUsersProviderService = mRetrofit.create(EndpointUsersProviderService.class);
}
private Retrofit createAuthorizedRetrofit(String accessToken) {
Retrofit mRetrofit;
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Request request = original.newBuilder()
.header("Authorization", "Bearer " + accessToken)
.method(original.method(), original.body())
.build();
return chain.proceed(request);
}
});
OkHttpClient client = httpClient.build();
mRetrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
return mRetrofit;
}
@Override
public void retrieve(UsersCallback usersCallback) {
Call<UsersResponse> friendsCall = mEndpointUsersProviderService.getUsers(
"friends",
400,
null);
friendsCall.enqueue(new Callback<UsersResponse>() {
@Override
public void onResponse(Call<UsersResponse> call, retrofit2.Response<UsersResponse> response) {
if (!response.isSuccessful()) {
usersCallback.retrieveError(new Exception("Error calling Users API"), "Error calling Users API");
return;
}
UsersResponse usersResponse = response.body();
List<UserListAdapter.User> adapterUsers = new ArrayList<>(usersResponse.total_entries);
for (User user : usersResponse.data.users) {
UserListAdapter.User adapterUser = new UserListAdapter.User();
adapterUser.connection = user.connection;
adapterUser.imageUrl = user.images.thumbnail;
adapterUser.name = user.username;
adapterUser.online = user.online;
adapterUsers.add(adapterUser);
}
usersCallback.retrieveOk(adapterUsers);
}
@Override
public void onFailure(Call<UsersResponse> call, Throwable t) {
usersCallback.retrieveError(new Exception(t), "Error calling Users API");
}
});
}
public interface EndpointUsersProviderService {
@GET("api/v1/users")
Call<UsersResponse> getUsers(@Query("filter") String filter,
@Query("per_page") int perPage,
@Query("online") Boolean online);
}
class UsersResponse {
public UsersResponse() {}
String status;
int current_page;
int total_pages;
int per_page;
int total_entries;
Data data;
}
class Data {
public Data() {}
List<User> users;
}
class User {
public User() {}
String username;
boolean online;
String connection;
Images images;
}
class Images {
public Images() {}
String hero;
String thumbnail;
String tiny;
}
}

View file

@ -0,0 +1,20 @@
package io.highfidelity.hifiinterface.provider;
import java.util.List;
import io.highfidelity.hifiinterface.view.UserListAdapter;
/**
* Created by cduarte on 6/13/18.
*/
public interface UsersProvider {
void retrieve(UsersProvider.UsersCallback usersCallback);
interface UsersCallback {
void retrieveOk(List<UserListAdapter.User> users);
void retrieveError(Exception e, String message);
}
}

View file

@ -0,0 +1,97 @@
package io.highfidelity.hifiinterface.view;
import android.content.Context;
import android.net.Uri;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
import java.util.List;
import io.highfidelity.hifiinterface.R;
import io.highfidelity.hifiinterface.provider.EndpointUsersProvider;
import io.highfidelity.hifiinterface.provider.UsersProvider;
/**
* Created by cduarte on 6/13/18.
*/
public class UserListAdapter extends RecyclerView.Adapter<UserListAdapter.ViewHolder> {
private UsersProvider mProvider;
private LayoutInflater mInflater;
private Context mContext;
private List<User> mUsers = new ArrayList<>();
public UserListAdapter(Context c, String accessToken) {
mContext = c;
mInflater = LayoutInflater.from(mContext);
mProvider = new EndpointUsersProvider(accessToken);
loadUsers();
}
private void loadUsers() {
mProvider.retrieve(new UsersProvider.UsersCallback() {
@Override
public void retrieveOk(List<User> users) {
mUsers = new ArrayList<>(users);
notifyDataSetChanged();
}
@Override
public void retrieveError(Exception e, String message) {
Log.e("[USERS]", message, e);
}
});
}
@Override
public UserListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.user_item, parent, false);
return new UserListAdapter.ViewHolder(view);
}
@Override
public void onBindViewHolder(UserListAdapter.ViewHolder holder, int position) {
User aUser = mUsers.get(position);
holder.mUsername.setText(aUser.name);
holder.mOnline.setText(aUser.online?"ONLINE":"OFFLINE");
Uri uri = Uri.parse(aUser.imageUrl);
Picasso.get().load(uri).into(holder.mImage);
}
@Override
public int getItemCount() {
return mUsers.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView mUsername;
TextView mOnline;
ImageView mImage;
public ViewHolder(View itemView) {
super(itemView);
mUsername = itemView.findViewById(R.id.userName);
mOnline = itemView.findViewById(R.id.userOnline);
mImage = itemView.findViewById(R.id.userImage);
}
}
public static class User {
public String name;
public String imageUrl;
public String connection;
public boolean online;
public User() {}
}
}

View file

@ -6,4 +6,13 @@
android:layout_height="match_parent"
android:background="@color/backgroundLight">
<android.support.v7.widget.RecyclerView
android:id="@+id/rvUsers"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="0dp"
android:layout_height="0dp" />
</android.support.constraint.ConstraintLayout>

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="56dp"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="@+id/userImage"
android:layout_width="40dp"
android:layout_height="40dp"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:id="@+id/userName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@id/userImage"/>
<TextView
android:id="@+id/userOnline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="end"
app:layout_constraintStart_toEndOf="@id/userName"
app:layout_constraintEnd_toEndOf="parent"/>
</android.support.constraint.ConstraintLayout>