Add live search for github users
parent
44de076a70
commit
17402765b6
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
|
@ -24,6 +24,14 @@ dependencies {
|
|||
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
|
||||
exclude group: 'com.android.support', module: 'support-annotations'
|
||||
})
|
||||
compile 'com.android.support:appcompat-v7:24.0.0-beta1'
|
||||
compile 'com.android.support:appcompat-v7:24.2.1'
|
||||
compile 'com.android.support:recyclerview-v7:24.2.1'
|
||||
compile 'com.google.code.gson:gson:2.4'
|
||||
compile 'com.squareup.retrofit2:retrofit:2.1.0'
|
||||
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
|
||||
compile 'com.jakewharton.rxbinding:rxbinding:0.4.0'
|
||||
testCompile 'junit:junit:4.12'
|
||||
|
||||
compile 'io.reactivex:rxandroid:1.2.1'
|
||||
compile 'io.reactivex:rxjava:1.2.0'
|
||||
}
|
||||
|
|
|
@ -2,13 +2,15 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.ensarsarajcic.reactivegithubsample">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity android:name=".MainActivity">
|
||||
<activity android:name=".views.MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
package com.ensarsarajcic.reactivegithubsample;
|
||||
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.ensarsarajcic.reactivegithubsample.models;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* Created by ensar on 03/10/16.
|
||||
*/
|
||||
public class GitHubRepo {
|
||||
public static final String TAG = GitHubRepo.class.getSimpleName();
|
||||
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.ensarsarajcic.reactivegithubsample.models;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by ensar on 03/10/16.
|
||||
*/
|
||||
public class GitHubSearchResponse {
|
||||
|
||||
private List<GitHubUser> items;
|
||||
|
||||
public List<GitHubUser> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public void setItems(List<GitHubUser> items) {
|
||||
this.items = items;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.ensarsarajcic.reactivegithubsample.models;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* Created by ensar on 03/10/16.
|
||||
*/
|
||||
public class GitHubUser {
|
||||
public static final String TAG = GitHubUser.class.getSimpleName();
|
||||
|
||||
private String login;
|
||||
private String html_url;
|
||||
private String avatar_url;
|
||||
|
||||
public String getLogin() {
|
||||
return login;
|
||||
}
|
||||
|
||||
public void setLogin(String login) {
|
||||
this.login = login;
|
||||
}
|
||||
|
||||
public String getHtml_url() {
|
||||
return html_url;
|
||||
}
|
||||
|
||||
public void setHtml_url(String html_url) {
|
||||
this.html_url = html_url;
|
||||
}
|
||||
|
||||
public String getAvatar_url() {
|
||||
return avatar_url;
|
||||
}
|
||||
|
||||
public void setAvatar_url(String avatar_url) {
|
||||
this.avatar_url = avatar_url;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.ensarsarajcic.reactivegithubsample.network;
|
||||
|
||||
import com.ensarsarajcic.reactivegithubsample.models.GitHubRepo;
|
||||
import com.ensarsarajcic.reactivegithubsample.models.GitHubSearchResponse;
|
||||
import com.ensarsarajcic.reactivegithubsample.models.GitHubUser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.Path;
|
||||
import retrofit2.http.Query;
|
||||
|
||||
/**
|
||||
* Created by ensar on 03/10/16.
|
||||
*/
|
||||
public interface GitHubApi {
|
||||
|
||||
@GET("/users")
|
||||
Call<List<GitHubUser>> getUsers(@Query("since") Integer since);
|
||||
|
||||
@GET("/search/users")
|
||||
Call<GitHubSearchResponse> searchForUsers(@Query("q") String query);
|
||||
|
||||
@GET("/users/{user}/repos")
|
||||
Call<List<GitHubRepo>> getUserRepos(@Path("user") String user);
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.ensarsarajcic.reactivegithubsample.network;
|
||||
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.converter.gson.GsonConverterFactory;
|
||||
|
||||
/**
|
||||
* Created by ensar on 03/10/16.
|
||||
*/
|
||||
public class RestClient {
|
||||
public static final String TAG = RestClient.class.getSimpleName();
|
||||
|
||||
private static GitHubApi gitHubApi;
|
||||
private static Retrofit restAdapter = null;
|
||||
|
||||
public static Retrofit getRestAdapter() {
|
||||
if(restAdapter == null) {
|
||||
Retrofit.Builder builder = new Retrofit.Builder()
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.baseUrl("https://api.github.com/");
|
||||
restAdapter = builder.build();
|
||||
}
|
||||
return restAdapter;
|
||||
}
|
||||
|
||||
|
||||
public static GitHubApi getGitHubApi() {
|
||||
if(gitHubApi == null) {
|
||||
gitHubApi = getRestAdapter().create(GitHubApi.class);
|
||||
}
|
||||
return gitHubApi;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,222 @@
|
|||
package com.ensarsarajcic.reactivegithubsample.views;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
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.ArrayAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.ensarsarajcic.reactivegithubsample.R;
|
||||
import com.ensarsarajcic.reactivegithubsample.models.GitHubRepo;
|
||||
import com.ensarsarajcic.reactivegithubsample.models.GitHubUser;
|
||||
import com.ensarsarajcic.reactivegithubsample.network.RestClient;
|
||||
import com.jakewharton.rxbinding.view.RxView;
|
||||
import com.jakewharton.rxbinding.widget.RxCompoundButton;
|
||||
import com.jakewharton.rxbinding.widget.RxTextView;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import rx.Observable;
|
||||
import rx.Subscriber;
|
||||
import rx.android.schedulers.AndroidSchedulers;
|
||||
import rx.functions.Func1;
|
||||
import rx.functions.Func2;
|
||||
import rx.schedulers.Schedulers;
|
||||
import rx.subscriptions.CompositeSubscription;
|
||||
|
||||
|
||||
/**
|
||||
* Created by ensar on 03/10/16.
|
||||
*/
|
||||
public class GitHubUsersAdapter extends RecyclerView.Adapter<GitHubUsersAdapter.GitHubUserViewHolder> {
|
||||
public static final String TAG = GitHubUsersAdapter.class.getSimpleName();
|
||||
|
||||
private List<GitHubUser> users;
|
||||
private CompositeSubscription compositeSubscription;
|
||||
|
||||
public GitHubUsersAdapter(List<GitHubUser> users) {
|
||||
this.users = users;
|
||||
compositeSubscription = new CompositeSubscription();
|
||||
}
|
||||
|
||||
public void setItems(List<GitHubUser> users) {
|
||||
this.users = users;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GitHubUserViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View itemView = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.list_item, parent, false);
|
||||
|
||||
return new GitHubUserViewHolder(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(final GitHubUserViewHolder holder, int position) {
|
||||
GitHubUser gitHubUser = users.get(position);
|
||||
holder.tvUserName.setText(gitHubUser.getLogin());
|
||||
holder.tvUserUrl.setText(gitHubUser.getHtml_url());
|
||||
|
||||
Observable<Bitmap> fetchImageObservable = Observable.just(gitHubUser).startWith(new GitHubUser())
|
||||
.map(new Func1<GitHubUser, Bitmap>() {
|
||||
@Override
|
||||
public Bitmap call(GitHubUser gitHubUser) {
|
||||
if(gitHubUser.getAvatar_url() == null) {
|
||||
return BitmapFactory.decodeResource(holder.itemView.getContext().getResources(), R.mipmap.ic_launcher);
|
||||
}
|
||||
|
||||
try {
|
||||
URL url = new URL(gitHubUser.getAvatar_url());
|
||||
return BitmapFactory.decodeStream(url.openConnection().getInputStream());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
})
|
||||
.filter(new Func1<Bitmap, Boolean>() {
|
||||
@Override
|
||||
public Boolean call(Bitmap bitmap) {
|
||||
return bitmap != null;
|
||||
}
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread());
|
||||
|
||||
Observable<List<GitHubRepo>> fetchUserReposObservable = Observable.just(gitHubUser)
|
||||
.map(new Func1<GitHubUser, List<GitHubRepo>>() {
|
||||
@Override
|
||||
public List<GitHubRepo> call(GitHubUser gitHubUser) {
|
||||
try {
|
||||
return RestClient.getGitHubApi().getUserRepos(gitHubUser.getLogin()).execute().body();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Log.e(TAG, "call: ", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
})
|
||||
.filter(new Func1<List<GitHubRepo>, Boolean>() {
|
||||
@Override
|
||||
public Boolean call(List<GitHubRepo> gitHubRepos) {
|
||||
return gitHubRepos != null;
|
||||
}
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread());
|
||||
|
||||
// Observable<Void> randomReposObservable = RxView.clicks(holder.tvRepos).subscribeOn(AndroidSchedulers.mainThread());
|
||||
//
|
||||
// compositeSubscription.add(randomReposObservable.subscribe(new Subscriber<Void>() {
|
||||
// @Override
|
||||
// public void onCompleted() {
|
||||
// Log.d(TAG, "onCompleted: ");
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onError(Throwable e) {
|
||||
// Log.d(TAG, "onError: ");
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onNext(Void aVoid) {
|
||||
// Log.d(TAG, "onNext: ");
|
||||
// }
|
||||
// }));
|
||||
//
|
||||
// Observable<List<GitHubRepo>> gitHubReposObservable = Observable.combineLatest(randomReposObservable, fetchUserReposObservable, new Func2<Void, List<GitHubRepo>, List<GitHubRepo>>() {
|
||||
// @Override
|
||||
// public List<GitHubRepo> call(Void aVoid, List<GitHubRepo> gitHubRepos) {
|
||||
// return gitHubRepos;
|
||||
// }
|
||||
// }).subscribeOn(AndroidSchedulers.mainThread());
|
||||
|
||||
Observable<List<String>> repoNamesObservable = fetchUserReposObservable.map(new Func1<List<GitHubRepo>, List<String>>() {
|
||||
@Override
|
||||
public List<String> call(List<GitHubRepo> gitHubRepos) {
|
||||
List<String> names = new ArrayList<String>();
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if(gitHubRepos.isEmpty()) break;
|
||||
int position = new Random().nextInt(gitHubRepos.size());
|
||||
names.add(gitHubRepos.get(position).getName());
|
||||
gitHubRepos.remove(position);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
compositeSubscription.add(fetchImageObservable.subscribe(new Subscriber<Bitmap>() {
|
||||
@Override
|
||||
public void onCompleted() {
|
||||
}
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(Bitmap bitmap) {
|
||||
holder.ivUser.setImageBitmap(bitmap);
|
||||
}
|
||||
}));
|
||||
|
||||
final ArrayAdapter<String> stringArrayAdapter = new ArrayAdapter<String>(holder.itemView.getContext(), R.layout.repo);
|
||||
holder.lvRepos.setAdapter(stringArrayAdapter);
|
||||
|
||||
compositeSubscription.add(repoNamesObservable.subscribe(new Subscriber<List<String>>() {
|
||||
@Override
|
||||
public void onCompleted() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(List<String> strings) {
|
||||
stringArrayAdapter.clear();
|
||||
stringArrayAdapter.addAll(strings);
|
||||
stringArrayAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return users.size();
|
||||
}
|
||||
|
||||
public class GitHubUserViewHolder extends RecyclerView.ViewHolder {
|
||||
private ImageView ivUser;
|
||||
private TextView tvUserName;
|
||||
private TextView tvUserUrl;
|
||||
private ListView lvRepos;
|
||||
|
||||
public GitHubUserViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
ivUser = (ImageView) itemView.findViewById(R.id.ivUser);
|
||||
tvUserName = (TextView) itemView.findViewById(R.id.tvUserName);
|
||||
tvUserUrl = (TextView) itemView.findViewById(R.id.tvUserUrl);
|
||||
lvRepos = (ListView) itemView.findViewById(R.id.lvRepos);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearSubscriptions() {
|
||||
if(!compositeSubscription.isUnsubscribed()) {
|
||||
compositeSubscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
package com.ensarsarajcic.reactivegithubsample.views;
|
||||
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.DefaultItemAnimator;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.EditText;
|
||||
|
||||
import com.ensarsarajcic.reactivegithubsample.R;
|
||||
import com.ensarsarajcic.reactivegithubsample.models.GitHubSearchResponse;
|
||||
import com.ensarsarajcic.reactivegithubsample.models.GitHubUser;
|
||||
import com.ensarsarajcic.reactivegithubsample.network.RestClient;
|
||||
import com.jakewharton.rxbinding.widget.RxTextView;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import rx.Observable;
|
||||
import rx.Subscriber;
|
||||
import rx.android.schedulers.AndroidSchedulers;
|
||||
import rx.functions.Func1;
|
||||
import rx.schedulers.Schedulers;
|
||||
import rx.subscriptions.CompositeSubscription;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
private static final String TAG = MainActivity.class.getSimpleName();
|
||||
|
||||
EditText etSearch;
|
||||
RecyclerView rvUsers;
|
||||
|
||||
CompositeSubscription compositeSubscription;
|
||||
|
||||
Observable<CharSequence> textChangeStream;
|
||||
Observable<List<GitHubUser>> gitHubSearchResponseStream;
|
||||
Observable<List<GitHubUser>> gitHubUsersResponseStream;
|
||||
Observable<List<GitHubUser>> gitHubAllResponsesStream;
|
||||
|
||||
GitHubUsersAdapter adapter;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
etSearch = (EditText) findViewById(R.id.etSearch);
|
||||
rvUsers = (RecyclerView) findViewById(R.id.rvUsers);
|
||||
|
||||
adapter = new GitHubUsersAdapter(new ArrayList<GitHubUser>());
|
||||
rvUsers.setAdapter(adapter);
|
||||
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
|
||||
rvUsers.setLayoutManager(layoutManager);
|
||||
rvUsers.setItemAnimator(new DefaultItemAnimator());
|
||||
|
||||
compositeSubscription = new CompositeSubscription();
|
||||
textChangeStream = RxTextView.textChanges(etSearch).
|
||||
debounce(1, TimeUnit.SECONDS).subscribeOn(AndroidSchedulers.mainThread());
|
||||
|
||||
gitHubSearchResponseStream = textChangeStream.filter(new Func1<CharSequence, Boolean>() {
|
||||
@Override
|
||||
public Boolean call(CharSequence charSequence) {
|
||||
return !TextUtils.isEmpty(charSequence);
|
||||
}
|
||||
})
|
||||
.map(new Func1<CharSequence, GitHubSearchResponse>() {
|
||||
@Override
|
||||
public GitHubSearchResponse call(CharSequence charSequence) {
|
||||
try {
|
||||
return RestClient.getGitHubApi().searchForUsers(charSequence.toString()).execute().body();
|
||||
} catch (IOException ioException) {
|
||||
ioException.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
})
|
||||
.filter(new Func1<GitHubSearchResponse, Boolean>() {
|
||||
@Override
|
||||
public Boolean call(GitHubSearchResponse gitHubSearchResponse) {
|
||||
return gitHubSearchResponse != null;
|
||||
}
|
||||
})
|
||||
.map(new Func1<GitHubSearchResponse, List<GitHubUser>>() {
|
||||
@Override
|
||||
public List<GitHubUser> call(GitHubSearchResponse gitHubSearchResponse) {
|
||||
return gitHubSearchResponse.getItems();
|
||||
}
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread());
|
||||
|
||||
gitHubUsersResponseStream = textChangeStream.
|
||||
filter(new Func1<CharSequence, Boolean>() {
|
||||
@Override
|
||||
public Boolean call(CharSequence charSequence) {
|
||||
return TextUtils.isEmpty(charSequence);
|
||||
}
|
||||
})
|
||||
.map(new Func1<CharSequence, List<GitHubUser>>() {
|
||||
@Override
|
||||
public List<GitHubUser> call(CharSequence charSequence) {
|
||||
try {
|
||||
return RestClient.getGitHubApi().getUsers(new Random().nextInt(1000)).execute().body();
|
||||
} catch (IOException ioException) {
|
||||
ioException.printStackTrace();
|
||||
return new ArrayList<GitHubUser>();
|
||||
}
|
||||
}
|
||||
})
|
||||
.subscribeOn(Schedulers.io()).
|
||||
observeOn(AndroidSchedulers.mainThread());
|
||||
|
||||
gitHubAllResponsesStream = Observable.merge(gitHubSearchResponseStream, gitHubUsersResponseStream);
|
||||
|
||||
compositeSubscription.add(gitHubAllResponsesStream.subscribe(new Subscriber<List<GitHubUser>>() {
|
||||
@Override
|
||||
public void onCompleted() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(List<GitHubUser> gitHubUsers) {
|
||||
adapter.setItems(gitHubUsers);
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
adapter.clearSubscriptions();
|
||||
if(!compositeSubscription.isUnsubscribed()) {
|
||||
compositeSubscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,10 +8,19 @@
|
|||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
tools:context="com.ensarsarajcic.reactivegithubsample.MainActivity">
|
||||
tools:context="com.ensarsarajcic.reactivegithubsample.views.MainActivity">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
<EditText
|
||||
android:id="@+id/etSearch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Hello World!" />
|
||||
android:text="Search" />
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/rvUsers"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/etSearch"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"/>
|
||||
</RelativeLayout>
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical" android:layout_width="match_parent"
|
||||
android:layout_height="200dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/tvUserName"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginRight="39dp"
|
||||
android:layout_marginEnd="39dp"
|
||||
android:layout_marginTop="29dp"
|
||||
android:textSize="20sp"
|
||||
android:ellipsize="end"
|
||||
android:text="USERNAME"
|
||||
android:textColor="@color/colorPrimary"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvUserUrl"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="https://userurl.com"
|
||||
android:layout_below="@+id/tvUserName"
|
||||
android:layout_alignLeft="@+id/tvUserName"
|
||||
android:layout_alignStart="@+id/tvUserName"
|
||||
android:autoLink="all"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvRepos"
|
||||
android:text="3 random repos:"
|
||||
android:layout_below="@+id/tvUserUrl"
|
||||
android:layout_alignLeft="@+id/tvUserUrl"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<ListView
|
||||
android:id="@+id/lvRepos"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_below="@+id/tvRepos"
|
||||
android:layout_toRightOf="@+id/ivUser"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivUser"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="100dp"
|
||||
android:src="@mipmap/ic_launcher"
|
||||
android:layout_marginRight="21dp"
|
||||
android:layout_marginEnd="21dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toLeftOf="@+id/tvUserName"
|
||||
android:layout_toStartOf="@+id/tvUserName" />
|
||||
|
||||
|
||||
</RelativeLayout>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent" android:layout_height="match_parent">
|
||||
|
||||
</TextView>
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#3F51B5</color>
|
||||
<color name="colorPrimary">#123DE1</color>
|
||||
<color name="colorPrimaryDark">#303F9F</color>
|
||||
<color name="colorAccent">#FF4081</color>
|
||||
<color name="colorAccent">#22AACC</color>
|
||||
</resources>
|
||||
|
|
Reference in New Issue