mirror of https://github.com/tasks/tasks
Remove section recycler view adapter library
parent
bbd9a24bc7
commit
a0b8338cec
@ -0,0 +1,87 @@
|
||||
package org.tasks.activities.attribution;
|
||||
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
import static com.google.common.collect.Lists.newArrayList;
|
||||
|
||||
import android.os.Bundle;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.tasks.R;
|
||||
import org.tasks.activities.attribution.AttributionViewModel.LibraryAttribution;
|
||||
import org.tasks.injection.ActivityComponent;
|
||||
import org.tasks.injection.ThemedInjectingAppCompatActivity;
|
||||
import timber.log.Timber;
|
||||
|
||||
public class AttributionActivity extends ThemedInjectingAppCompatActivity {
|
||||
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
|
||||
@BindView(R.id.list)
|
||||
RecyclerView recyclerView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.activity_attributions);
|
||||
|
||||
ButterKnife.bind(this);
|
||||
|
||||
toolbar.setTitle(R.string.third_party_licenses);
|
||||
toolbar.setNavigationIcon(R.drawable.ic_outline_arrow_back_24px);
|
||||
toolbar.setNavigationOnClickListener(v -> finish());
|
||||
themeColor.apply(toolbar);
|
||||
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
new ViewModelProvider(this)
|
||||
.get(AttributionViewModel.class)
|
||||
.observe(this, this::updateAttributions);
|
||||
}
|
||||
|
||||
private void updateAttributions(List<LibraryAttribution> libraryAttributions) {
|
||||
List<AttributionRow> rows = new ArrayList<>();
|
||||
ImmutableListMultimap<String, LibraryAttribution> index =
|
||||
Multimaps.index(libraryAttributions, LibraryAttribution::getLicense);
|
||||
ArrayList<String> licenses = new ArrayList<>(index.keySet());
|
||||
Collections.sort(licenses);
|
||||
for (String license : licenses) {
|
||||
rows.add(new AttributionRow(license));
|
||||
ImmutableList<LibraryAttribution> libraries = index.get(license);
|
||||
ImmutableListMultimap<String, LibraryAttribution> idx =
|
||||
Multimaps.index(libraries, LibraryAttribution::getCopyrightHolder);
|
||||
List<String> copyrightHolders = newArrayList(idx.keySet());
|
||||
Collections.sort(copyrightHolders);
|
||||
for (String copyrightHolder : copyrightHolders) {
|
||||
List<String> libs = newArrayList(transform(idx.get(copyrightHolder),
|
||||
a -> "\u2022 " + a.getLibraryName()));
|
||||
Collections.sort(libs);
|
||||
rows.add(new AttributionRow(copyrightHolder, Joiner.on("\n").join(libs)));
|
||||
}
|
||||
}
|
||||
recyclerView.setAdapter(new AttributionAdapter(rows));
|
||||
Timber.d(libraryAttributions.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inject(ActivityComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package org.tasks.activities.attribution;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
|
||||
import java.util.List;
|
||||
import org.tasks.R;
|
||||
|
||||
public class AttributionAdapter extends RecyclerView.Adapter<ViewHolder> {
|
||||
|
||||
private final List<AttributionRow> rows;
|
||||
|
||||
AttributionAdapter(List<AttributionRow> rows) {
|
||||
this.rows = rows;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
||||
return viewType == 0
|
||||
? new LicenseHeader(inflater.inflate(R.layout.row_attribution_header, parent, false))
|
||||
: new LicenseRow(inflater.inflate(R.layout.row_attribution, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
AttributionRow row = rows.get(position);
|
||||
if (getItemViewType(position) == 0) {
|
||||
((LicenseHeader) holder).bind(row.getLicense());
|
||||
} else {
|
||||
((LicenseRow) holder).bind(row.getCopyrightHolder(), row.getLibraries());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return rows.get(position).isHeader() ? 0 : 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return rows.size();
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package org.tasks.activities.attribution;
|
||||
|
||||
public class AttributionRow {
|
||||
|
||||
private final boolean isHeader;
|
||||
private final String license;
|
||||
private final String copyrightHolder;
|
||||
private final String libraries;
|
||||
|
||||
AttributionRow(String license) {
|
||||
this.license = license;
|
||||
isHeader = true;
|
||||
copyrightHolder = null;
|
||||
libraries = null;
|
||||
}
|
||||
|
||||
AttributionRow(String copyrightHolder, String libraries) {
|
||||
this.copyrightHolder = copyrightHolder;
|
||||
this.libraries = libraries;
|
||||
isHeader = false;
|
||||
license = null;
|
||||
}
|
||||
|
||||
boolean isHeader() {
|
||||
return isHeader;
|
||||
}
|
||||
|
||||
public String getLicense() {
|
||||
return license;
|
||||
}
|
||||
|
||||
String getCopyrightHolder() {
|
||||
return copyrightHolder;
|
||||
}
|
||||
|
||||
public String getLibraries() {
|
||||
return libraries;
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package org.tasks.activities.attribution;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.Observer;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import io.reactivex.Single;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import timber.log.Timber;
|
||||
|
||||
@SuppressWarnings({"WeakerAccess", "RedundantSuppression"})
|
||||
public class AttributionViewModel extends androidx.lifecycle.ViewModel {
|
||||
private final MutableLiveData<List<LibraryAttribution>> attributions = new MutableLiveData<>();
|
||||
private final CompositeDisposable disposables = new CompositeDisposable();
|
||||
private boolean loaded;
|
||||
|
||||
void observe(AppCompatActivity activity, Observer<List<LibraryAttribution>> observer) {
|
||||
attributions.observe(activity, observer);
|
||||
load(activity);
|
||||
}
|
||||
|
||||
private void load(Context context) {
|
||||
if (loaded) {
|
||||
return;
|
||||
}
|
||||
loaded = true;
|
||||
disposables.add(
|
||||
Single.fromCallable(
|
||||
() -> {
|
||||
InputStream licenses = context.getAssets().open("licenses.json");
|
||||
InputStreamReader reader =
|
||||
new InputStreamReader(licenses, StandardCharsets.UTF_8);
|
||||
AttributionList list =
|
||||
new GsonBuilder().create().fromJson(reader, AttributionList.class);
|
||||
return list.libraries;
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(attributions::setValue, Timber::e));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCleared() {
|
||||
disposables.dispose();
|
||||
}
|
||||
|
||||
static class AttributionList {
|
||||
List<LibraryAttribution> libraries;
|
||||
}
|
||||
|
||||
static class LibraryAttribution {
|
||||
String copyrightHolder;
|
||||
String license;
|
||||
String libraryName;
|
||||
|
||||
String getCopyrightHolder() {
|
||||
return copyrightHolder;
|
||||
}
|
||||
|
||||
@Keep
|
||||
String getLicense() {
|
||||
return license;
|
||||
}
|
||||
|
||||
String getLibraryName() {
|
||||
return libraryName;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package org.tasks.activities.attribution;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import org.tasks.R;
|
||||
|
||||
class LicenseHeader extends RecyclerView.ViewHolder {
|
||||
@BindView(R.id.license_name)
|
||||
TextView licenseName;
|
||||
|
||||
LicenseHeader(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
ButterKnife.bind(this, itemView);
|
||||
}
|
||||
|
||||
void bind(String license) {
|
||||
licenseName.setText(license);
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package org.tasks.activities.attribution;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import org.tasks.R;
|
||||
|
||||
class LicenseRow extends RecyclerView.ViewHolder {
|
||||
|
||||
@BindView(R.id.copyright_holder)
|
||||
TextView copyrightHolder;
|
||||
|
||||
@BindView(R.id.libraries)
|
||||
TextView libraries;
|
||||
|
||||
LicenseRow(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
ButterKnife.bind(this, itemView);
|
||||
}
|
||||
|
||||
void bind(String copyrightHolder, String libraries) {
|
||||
this.copyrightHolder.setText(copyrightHolder);
|
||||
this.libraries.setText(libraries);
|
||||
}
|
||||
}
|
@ -1,142 +0,0 @@
|
||||
package org.tasks.preferences;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import io.github.luizgrp.sectionedrecyclerviewadapter.SectionedRecyclerViewAdapter;
|
||||
import io.reactivex.Single;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.tasks.R;
|
||||
import org.tasks.injection.ActivityComponent;
|
||||
import org.tasks.injection.ThemedInjectingAppCompatActivity;
|
||||
import timber.log.Timber;
|
||||
|
||||
public class AttributionActivity extends ThemedInjectingAppCompatActivity {
|
||||
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
|
||||
@BindView(R.id.list)
|
||||
RecyclerView recyclerView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.activity_attributions);
|
||||
|
||||
ButterKnife.bind(this);
|
||||
|
||||
toolbar.setTitle(R.string.third_party_licenses);
|
||||
toolbar.setNavigationIcon(R.drawable.ic_outline_arrow_back_24px);
|
||||
toolbar.setNavigationOnClickListener(v -> finish());
|
||||
themeColor.apply(toolbar);
|
||||
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
new ViewModelProvider(this).get(ViewModel.class).observe(this, this::updateAttributions);
|
||||
}
|
||||
|
||||
private void updateAttributions(List<LibraryAttribution> libraryAttributions) {
|
||||
SectionedRecyclerViewAdapter adapter = new SectionedRecyclerViewAdapter();
|
||||
ImmutableListMultimap<String, LibraryAttribution> index =
|
||||
Multimaps.index(libraryAttributions, LibraryAttribution::getLicense);
|
||||
ArrayList<String> licenses = new ArrayList<>(index.keySet());
|
||||
Collections.sort(licenses);
|
||||
for (String license : licenses) {
|
||||
adapter.addSection(new AttributionSection(license, index.get(license)));
|
||||
}
|
||||
recyclerView.setAdapter(adapter);
|
||||
Timber.d(libraryAttributions.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inject(ActivityComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
|
||||
static class AttributionList {
|
||||
List<LibraryAttribution> libraries;
|
||||
}
|
||||
|
||||
static class LibraryAttribution {
|
||||
String copyrightHolder;
|
||||
String license;
|
||||
String libraryName;
|
||||
|
||||
String getCopyrightHolder() {
|
||||
return copyrightHolder;
|
||||
}
|
||||
|
||||
@Keep
|
||||
String getLicense() {
|
||||
return license;
|
||||
}
|
||||
|
||||
String getLibraryName() {
|
||||
return libraryName;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"WeakerAccess", "RedundantSuppression"})
|
||||
public static class ViewModel extends androidx.lifecycle.ViewModel {
|
||||
private final MutableLiveData<List<LibraryAttribution>> attributions = new MutableLiveData<>();
|
||||
private final CompositeDisposable disposables = new CompositeDisposable();
|
||||
private boolean loaded;
|
||||
|
||||
void observe(AppCompatActivity activity, Observer<List<LibraryAttribution>> observer) {
|
||||
attributions.observe(activity, observer);
|
||||
load(activity);
|
||||
}
|
||||
|
||||
private void load(Context context) {
|
||||
if (loaded) {
|
||||
return;
|
||||
}
|
||||
loaded = true;
|
||||
disposables.add(
|
||||
Single.fromCallable(
|
||||
() -> {
|
||||
InputStream licenses = context.getAssets().open("licenses.json");
|
||||
InputStreamReader reader =
|
||||
new InputStreamReader(licenses, StandardCharsets.UTF_8);
|
||||
AttributionList list =
|
||||
new GsonBuilder().create().fromJson(reader, AttributionList.class);
|
||||
return list.libraries;
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(attributions::setValue, Timber::e));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCleared() {
|
||||
disposables.dispose();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,110 +0,0 @@
|
||||
package org.tasks.preferences;
|
||||
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
import static com.google.common.collect.Lists.newArrayList;
|
||||
import static com.google.common.collect.Maps.newLinkedHashMap;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
import io.github.luizgrp.sectionedrecyclerviewadapter.SectionParameters;
|
||||
import io.github.luizgrp.sectionedrecyclerviewadapter.StatelessSection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import org.tasks.R;
|
||||
import org.tasks.preferences.AttributionActivity.LibraryAttribution;
|
||||
|
||||
class AttributionSection extends StatelessSection {
|
||||
|
||||
private final String license;
|
||||
private final List<Entry<String, String>> attributions;
|
||||
|
||||
AttributionSection(String license, List<LibraryAttribution> attributions) {
|
||||
super(
|
||||
SectionParameters.builder()
|
||||
.itemResourceId(R.layout.row_attribution)
|
||||
.headerResourceId(R.layout.row_attribution_header)
|
||||
.build());
|
||||
this.license = license;
|
||||
ImmutableListMultimap<String, LibraryAttribution> index =
|
||||
Multimaps.index(attributions, LibraryAttribution::getCopyrightHolder);
|
||||
List<String> copyrightHolders = newArrayList(index.keySet());
|
||||
Collections.sort(copyrightHolders);
|
||||
Map<String, String> map = newLinkedHashMap();
|
||||
for (String copyrightHolder : copyrightHolders) {
|
||||
List<String> libraries = newArrayList(transform(index.get(copyrightHolder),
|
||||
a -> "\u2022 " + a.getLibraryName()));
|
||||
Collections.sort(libraries);
|
||||
map.put(copyrightHolder, Joiner.on("\n").join(libraries));
|
||||
}
|
||||
this.attributions = newArrayList(map.entrySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getContentItemsTotal() {
|
||||
return attributions.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder getHeaderViewHolder(View view) {
|
||||
return new LicenseHeader(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder getItemViewHolder(View view) {
|
||||
return new LicenseRow(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindHeaderViewHolder(ViewHolder holder) {
|
||||
((LicenseHeader) holder).bind(license);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindItemViewHolder(ViewHolder holder, int position) {
|
||||
Entry<String, String> entry = attributions.get(position);
|
||||
((LicenseRow) holder).bind(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
static class LicenseHeader extends RecyclerView.ViewHolder {
|
||||
@BindView(R.id.license_name)
|
||||
TextView licenseName;
|
||||
|
||||
LicenseHeader(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
ButterKnife.bind(this, itemView);
|
||||
}
|
||||
|
||||
void bind(String license) {
|
||||
licenseName.setText(license);
|
||||
}
|
||||
}
|
||||
|
||||
static class LicenseRow extends RecyclerView.ViewHolder {
|
||||
|
||||
@BindView(R.id.copyright_holder)
|
||||
TextView copyrightHolder;
|
||||
|
||||
@BindView(R.id.libraries)
|
||||
TextView libraries;
|
||||
|
||||
LicenseRow(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
ButterKnife.bind(this, itemView);
|
||||
}
|
||||
|
||||
void bind(String copyrightHolder, String libraries) {
|
||||
this.copyrightHolder.setText(copyrightHolder);
|
||||
this.libraries.setText(libraries);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue