#3468 Switch from RvRenderer to AdapterDelegates - replace SearchDepictionsRenderer

This commit is contained in:
Sean Mac Gillicuddy 2020-05-12 12:51:17 +01:00
parent 057d11a0e0
commit 88c307d265
14 changed files with 146 additions and 279 deletions

View file

@ -11,7 +11,7 @@ apply from: 'quality.gradle'
def isRunningOnTravisAndIsNotPRBuild = System.getenv("CI") == "true" && file('../play.p12').exists()
if(isRunningOnTravisAndIsNotPRBuild) {
if (isRunningOnTravisAndIsNotPRBuild) {
apply plugin: 'com.github.triplet.play'
}
@ -43,8 +43,9 @@ dependencies {
implementation 'com.dinuscxj:circleprogressbar:1.1.1'
implementation 'com.karumi:dexter:5.0.0'
implementation "com.jakewharton:butterknife:$BUTTERKNIFE_VERSION"
kapt "com.jakewharton:butterknife-compiler:$BUTTERKNIFE_VERSION"
implementation "com.hannesdorfmann:adapterdelegates4-kotlin-dsl-layoutcontainer:$ADAPTER_DELEGATES_VERSION"
implementation "com.hannesdorfmann:adapterdelegates4-pagination:$ADAPTER_DELEGATES_VERSION"
// Logging
implementation 'ch.acra:acra-dialog:5.3.0'
@ -112,7 +113,8 @@ dependencies {
implementation "androidx.room:room-runtime:$ROOM_VERSION"
implementation "androidx.room:room-ktx:$ROOM_VERSION"
implementation "androidx.room:room-rxjava2:$ROOM_VERSION"
kapt "androidx.room:room-compiler:$ROOM_VERSION" // For Kotlin use kapt instead of annotationProcessor
kapt "androidx.room:room-compiler:$ROOM_VERSION"
// For Kotlin use kapt instead of annotationProcessor
implementation 'com.squareup.retrofit2:retrofit:2.8.1'
testImplementation "androidx.arch.core:core-testing:2.1.0"
@ -168,7 +170,7 @@ android {
test.resources.srcDirs += 'src/main/resoures'
}
signingConfigs {
signingConfigs {
release
}
@ -177,7 +179,7 @@ android {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
testProguardFile 'test-proguard-rules.txt'
if(isRunningOnTravisAndIsNotPRBuild) {
if (isRunningOnTravisAndIsNotPRBuild) {
signingConfig signingConfigs.release
}
}
@ -206,7 +208,7 @@ android {
productFlavors {
prod {
applicationId 'fr.free.nrw.commons'
applicationId 'fr.free.nrw.commons'
buildConfigField "String", "WIKIMEDIA_API_POTD", "\"https://commons.wikimedia.org/w/api.php?action=featuredfeed&feed=potd&feedformat=rss&language=en\""
buildConfigField "String", "WIKIMEDIA_API_HOST", "\"https://commons.wikimedia.org/w/api.php\""
@ -287,7 +289,7 @@ android {
buildToolsVersion buildToolsVersion
}
if(isRunningOnTravisAndIsNotPRBuild) {
if (isRunningOnTravisAndIsNotPRBuild) {
play {
track = "alpha"
userFraction = 1

View file

@ -39,8 +39,8 @@ public class DepictedImagesPresenter implements DepictedImagesContract.UserActio
* Wikibase enitityId for the depicted Item
* Ex: Q9394
*/
private String entityId = null;
private List<Media> queryList = new ArrayList<>();
private String entityId;
@Inject
public DepictedImagesPresenter(@Named("default_preferences") JsonKvStore depictionKvStore, DepictsClient depictsClient, MediaClient mediaClient, @Named(IO_THREAD) Scheduler ioScheduler,
@ -68,6 +68,7 @@ public class DepictedImagesPresenter implements DepictedImagesContract.UserActio
@SuppressLint("CheckResult")
@Override
public void initList(String entityId) {
this.entityId = entityId;
view.setLoadingStatus(true);
view.progressBarVisible(true);
view.setIsLastPage(false);

View file

@ -17,12 +17,10 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
import butterknife.ButterKnife;
import com.pedrogomez.renderers.RVRendererAdapter;
import dagger.android.support.DaggerFragment;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.depictions.WikidataItemDetailsActivity;
import fr.free.nrw.commons.explore.depictions.SearchDepictionsAdapterFactory;
import fr.free.nrw.commons.explore.depictions.SearchDepictionsRenderer;
import fr.free.nrw.commons.explore.depictions.DepictionAdapter;
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
import fr.free.nrw.commons.utils.NetworkUtils;
import fr.free.nrw.commons.utils.ViewUtil;
@ -30,6 +28,7 @@ import java.io.IOException;
import java.util.List;
import java.util.Locale;
import javax.inject.Inject;
import kotlin.Unit;
/**
* Fragment for parent classes and child classes of Depicted items in Explore
@ -48,7 +47,7 @@ public class SubDepictionListFragment extends DaggerFragment implements SubDepic
* Keeps a record of whether current instance of the fragment if of SubClass or ParentClass
*/
private boolean isParentClass = false;
private RVRendererAdapter<DepictedItem> depictionsAdapter;
private DepictionAdapter depictionsAdapter;
RecyclerView.LayoutManager layoutManager;
/**
* Stores entityId for the depiction
@ -61,20 +60,6 @@ public class SubDepictionListFragment extends DaggerFragment implements SubDepic
@Inject SubDepictionListPresenter presenter;
private final SearchDepictionsAdapterFactory adapterFactory = new SearchDepictionsAdapterFactory(new SearchDepictionsRenderer.DepictCallback() {
@Override
public void depictsClicked(DepictedItem item) {
// Open SubDepiction Details page
getActivity().finish();
WikidataItemDetailsActivity.startYourself(getContext(), item);
}
});
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
private void initViews() {
if (getArguments() != null) {
depictsName = getArguments().getString("wikidataItemName");
@ -115,7 +100,12 @@ public class SubDepictionListFragment extends DaggerFragment implements SubDepic
}
initViews();
depictionsRecyclerView.setLayoutManager(layoutManager);
depictionsAdapter = adapterFactory.create();
depictionsAdapter = new DepictionAdapter(depictedItem -> {
// Open SubDepiction Details page
getActivity().finish();
WikidataItemDetailsActivity.startYourself(getContext(), depictedItem);
return Unit.INSTANCE;
});
depictionsRecyclerView.setAdapter(depictionsAdapter);
return v;
}
@ -130,14 +120,7 @@ public class SubDepictionListFragment extends DaggerFragment implements SubDepic
progressBar.setVisibility(View.GONE);
depictionNotFound.setVisibility(GONE);
bottomProgressBar.setVisibility(GONE);
int itemCount=layoutManager.getItemCount();
depictionsAdapter.addAll(mediaList);
depictionsRecyclerView.getRecycledViewPool().clear();
if(itemCount!=0) {
depictionsAdapter.notifyItemRangeInserted(itemCount, mediaList.size()-1);
}else{
depictionsAdapter.notifyDataSetChanged();
}
}
@Override

View file

@ -9,7 +9,8 @@ data class Binding(
val itemLabel: SparqInfo,
val itemDescription: SparqInfo? = null
) {
val id: String by lazy { item.value.substringAfterLast("/") }
val id: String
get() = item.value.substringAfterLast("/")
}
data class SparqInfo(val type: String, val value: String)

View file

@ -5,23 +5,16 @@ import android.text.TextUtils;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.viewpager.widget.ViewPager;
import butterknife.BindView;
import butterknife.ButterKnife;
import com.google.android.material.tabs.TabLayout;
import com.jakewharton.rxbinding2.view.RxView;
import com.jakewharton.rxbinding2.widget.RxSearchView;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import butterknife.BindView;
import butterknife.ButterKnife;
import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.category.CategoryImagesCallback;
@ -34,6 +27,10 @@ import fr.free.nrw.commons.theme.NavigationBaseActivity;
import fr.free.nrw.commons.utils.FragmentUtils;
import fr.free.nrw.commons.utils.ViewUtil;
import io.reactivex.android.schedulers.AndroidSchedulers;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import timber.log.Timber;
/**
* Represents search screen of this app
@ -111,35 +108,35 @@ public class SearchActivity extends NavigationBaseActivity
.takeUntil(RxView.detaches(searchView))
.debounce(500, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe( query -> {
this.query = query.toString();
//update image list
if (!TextUtils.isEmpty(query)) {
viewPager.setVisibility(View.VISIBLE);
tabLayout.setVisibility(View.VISIBLE);
searchHistoryContainer.setVisibility(View.GONE);
.subscribe(query -> {
this.query = query.toString();
//update image list
if (!TextUtils.isEmpty(query)) {
viewPager.setVisibility(View.VISIBLE);
tabLayout.setVisibility(View.VISIBLE);
searchHistoryContainer.setVisibility(View.GONE);
if (FragmentUtils.isFragmentUIActive(searchDepictionsFragment)) {
searchDepictionsFragment.updateDepictionList(query.toString());
}
if (FragmentUtils.isFragmentUIActive(searchImageFragment)) {
searchImageFragment.updateImageList(query.toString());
}
if (FragmentUtils.isFragmentUIActive(searchCategoryFragment)) {
searchCategoryFragment.updateCategoryList(query.toString());
}
}else {
//Open RecentSearchesFragment
recentSearchesFragment.updateRecentSearches();
viewPager.setVisibility(View.GONE);
tabLayout.setVisibility(View.GONE);
setSearchHistoryFragment();
searchHistoryContainer.setVisibility(View.VISIBLE);
if (FragmentUtils.isFragmentUIActive(searchDepictionsFragment)) {
searchDepictionsFragment.updateDepictionList(query.toString());
}
if (FragmentUtils.isFragmentUIActive(searchImageFragment)) {
searchImageFragment.updateImageList(query.toString());
}
if (FragmentUtils.isFragmentUIActive(searchCategoryFragment)) {
searchCategoryFragment.updateCategoryList(query.toString());
}
} else {
//Open RecentSearchesFragment
recentSearchesFragment.updateRecentSearches();
viewPager.setVisibility(View.GONE);
tabLayout.setVisibility(View.GONE);
setSearchHistoryFragment();
searchHistoryContainer.setVisibility(View.VISIBLE);
}
}, Timber::e
));
}

View file

@ -0,0 +1,30 @@
package fr.free.nrw.commons.explore.depictions
import androidx.recyclerview.widget.DiffUtil
import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
class DepictionAdapter(clickListener: (DepictedItem) -> Unit) :
AsyncListDifferDelegationAdapter<DepictedItem>(
DiffUtil,
depictionDelegate(clickListener)
) {
fun addAll(newResults: List<DepictedItem>) {
items = (items ?: emptyList<DepictedItem>()) + newResults
}
fun clear() {
items = emptyList()
}
}
object DiffUtil : DiffUtil.ItemCallback<DepictedItem>() {
override fun areItemsTheSame(oldItem: DepictedItem, newItem: DepictedItem) =
oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: DepictedItem, newItem: DepictedItem) =
oldItem == newItem
}

View file

@ -0,0 +1,21 @@
package fr.free.nrw.commons.explore.depictions
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateLayoutContainer
import fr.free.nrw.commons.R
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
import kotlinx.android.synthetic.main.item_depictions.*
fun depictionDelegate(onDepictionClicked: (DepictedItem) -> Unit) =
adapterDelegateLayoutContainer<DepictedItem, DepictedItem>(R.layout.item_depictions) {
containerView.setOnClickListener { onDepictionClicked(item) }
bind {
depicts_label.text = item.name
description.text = item.description
if (item.imageUrl?.isNotBlank() == true) {
depicts_image.setImageURI(item.imageUrl)
} else {
depicts_image.setActualImageResource(R.drawable.ic_wikidata_logo_24dp)
}
}
}

View file

@ -3,7 +3,6 @@ package fr.free.nrw.commons.explore.depictions
import fr.free.nrw.commons.BuildConfig
import fr.free.nrw.commons.Media
import fr.free.nrw.commons.depictions.models.DepictionResponse
import fr.free.nrw.commons.depictions.subClass.models.Binding
import fr.free.nrw.commons.depictions.subClass.models.SparqlResponse
import fr.free.nrw.commons.media.MediaInterface
import fr.free.nrw.commons.upload.depicts.DepictsInterface
@ -20,8 +19,9 @@ import java.util.*
import javax.inject.Inject
import javax.inject.Singleton
const val LARGE_IMAGE_SIZE="640px"
const val THUMB_IMAGE_SIZE="70px"
const val LARGE_IMAGE_SIZE = "640px"
const val THUMB_IMAGE_SIZE = "70px"
/**
* Depicts Client to handle custom calls to Commons Wikibase APIs
*/
@ -79,7 +79,11 @@ class DepictsClient @Inject constructor(
}
fun toDepictions(sparqlResponse: Observable<SparqlResponse>): Observable<List<DepictedItem>> {
return sparqlResponse.map { it.results.bindings.joinToString("|", transform = Binding::id) }
return sparqlResponse.map {
it.results.bindings.joinToString("|") { binding ->
binding.id
}
}
.flatMap { getEntities(it).toObservable() }
.map { it.entities()?.values?.map(::DepictedItem) ?: emptyList() }
}

View file

@ -1,31 +0,0 @@
package fr.free.nrw.commons.explore.depictions;
import com.pedrogomez.renderers.ListAdapteeCollection;
import com.pedrogomez.renderers.RVRendererAdapter;
import com.pedrogomez.renderers.RendererBuilder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
/**
* Adapter factory for Items in Explore
*/
public class SearchDepictionsAdapterFactory {
private final SearchDepictionsRenderer.DepictCallback listener;
public SearchDepictionsAdapterFactory(SearchDepictionsRenderer.DepictCallback listener) {
this.listener = listener;
}
public RVRendererAdapter<DepictedItem> create() {
List<DepictedItem> searchImageItemList = new ArrayList<>();
RendererBuilder<DepictedItem> builder = new RendererBuilder<DepictedItem>().bind(DepictedItem.class, new SearchDepictionsRenderer(listener));
ListAdapteeCollection<DepictedItem> collection = new ListAdapteeCollection<>(
searchImageItemList != null ? searchImageItemList : Collections.<DepictedItem>emptyList());
return new RVRendererAdapter<>(builder, collection);
}
}

View file

@ -2,6 +2,7 @@ package fr.free.nrw.commons.explore.depictions;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static fr.free.nrw.commons.explore.depictions.DepictionAdapterDelegatesKt.depictionDelegate;
import android.content.Context;
import android.content.res.Configuration;
@ -12,12 +13,13 @@ import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil.ItemCallback;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
import butterknife.ButterKnife;
import com.pedrogomez.renderers.RVRendererAdapter;
import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.depictions.WikidataItemDetailsActivity;
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
@ -28,6 +30,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import javax.inject.Inject;
import kotlin.Unit;
/**
* Display depictions in search fragment
@ -42,24 +45,17 @@ public class SearchDepictionsFragment extends CommonsDaggerSupportFragment imple
TextView depictionNotFound;
@BindView(R.id.bottomProgressBar)
ProgressBar bottomProgressBar;
RecyclerView.LayoutManager layoutManager;
private RecyclerView.LayoutManager layoutManager;
private boolean isLoading = true;
private int PAGE_SIZE = 25;
private final int PAGE_SIZE = 25;
@Inject
SearchDepictionsFragmentPresenter presenter;
private final SearchDepictionsAdapterFactory adapterFactory = new SearchDepictionsAdapterFactory(new SearchDepictionsRenderer.DepictCallback() {
@Override
public void depictsClicked(DepictedItem item) {
WikidataItemDetailsActivity.startYourself(getContext(), item);
presenter.saveQuery();
}
});
private RVRendererAdapter<DepictedItem> depictionsAdapter;
private DepictionAdapter depictionsAdapter;
private boolean isLastPage;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_browse_image, container, false);
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_browse_image, container, false);
ButterKnife.bind(this, rootView);
if (getActivity().getResources().getConfiguration().orientation
== Configuration.ORIENTATION_PORTRAIT) {
@ -68,20 +64,25 @@ public class SearchDepictionsFragment extends CommonsDaggerSupportFragment imple
layoutManager = new GridLayoutManager(getContext(), 2);
}
depictionsRecyclerView.setLayoutManager(layoutManager);
depictionsAdapter = adapterFactory.create();
depictionsAdapter = new DepictionAdapter(
depictedItem -> {
WikidataItemDetailsActivity.startYourself(getContext(), depictedItem);
presenter.saveQuery();
return Unit.INSTANCE;
});
depictionsRecyclerView.setAdapter(depictionsAdapter);
depictionsRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
public void onScrollStateChanged(final RecyclerView recyclerView, final int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, final int dy) {
super.onScrolled(recyclerView, dx, dy);
int visibleItemCount = layoutManager.getChildCount();
int totalItemCount = layoutManager.getItemCount();
final int visibleItemCount = layoutManager.getChildCount();
final int totalItemCount = layoutManager.getItemCount();
int firstVisibleItemPosition=0;
if(layoutManager instanceof GridLayoutManager){
firstVisibleItemPosition=((GridLayoutManager) layoutManager).findFirstVisibleItemPosition();
@ -108,12 +109,12 @@ public class SearchDepictionsFragment extends CommonsDaggerSupportFragment imple
/**
* Fetch PAGE_SIZE number of items
*/
private void loadMoreItems(boolean reInitialise) {
private void loadMoreItems(final boolean reInitialise) {
presenter.updateDepictionList(presenter.getQuery(),PAGE_SIZE, reInitialise);
}
@Override
public void onAttach(Context context) {
public void onAttach(final Context context) {
super.onAttach(context);
presenter.onAttachView(this);
}
@ -124,7 +125,7 @@ public class SearchDepictionsFragment extends CommonsDaggerSupportFragment imple
*
* @param query string searched in the Explore Activity
*/
public void updateDepictionList(String query) {
public void updateDepictionList(final String query) {
presenter.initializeQuery(query);
if (!NetworkUtils.isInternetConnectionEstablished(getContext())) {
handleNoInternet();
@ -142,22 +143,10 @@ public class SearchDepictionsFragment extends CommonsDaggerSupportFragment imple
progressBar.setVisibility(GONE);
bottomProgressBar.setVisibility(GONE);
depictionNotFound.setVisibility(VISIBLE);
String no_depiction = getString(R.string.depictions_not_found);
final String no_depiction = getString(R.string.depictions_not_found);
depictionNotFound.setText(String.format(Locale.getDefault(), no_depiction, presenter.getQuery()));
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onResume() {
super.onResume();
depictionsAdapter.clear();
depictionsRecyclerView.cancelPendingInputEvents();
}
/**
* Handles the UI updates for no internet scenario
*/
@ -172,24 +161,18 @@ public class SearchDepictionsFragment extends CommonsDaggerSupportFragment imple
* like hiding empty labels, hiding progressbar and notifying the apdapter that list of items has been fetched from the API
*/
@Override
public void onSuccess(List<DepictedItem> mediaList) {
public void onSuccess(final List<DepictedItem> mediaList) {
isLoading = false;
progressBar.setVisibility(View.GONE);
progressBar.setVisibility(GONE);
depictionNotFound.setVisibility(GONE);
bottomProgressBar.setVisibility(GONE);
int itemCount = layoutManager.getItemCount();
depictionsAdapter.addAll(mediaList);
if(itemCount!=0) {
depictionsAdapter.notifyItemRangeInserted(itemCount, mediaList.size()-1);
}else{
depictionsAdapter.notifyDataSetChanged();
}
}
@Override
public void loadingDepictions(boolean isLoading) {
public void loadingDepictions(final boolean isLoading) {
depictionNotFound.setVisibility(GONE);
bottomProgressBar.setVisibility(View.VISIBLE);
bottomProgressBar.setVisibility(VISIBLE);
progressBar.setVisibility(GONE);
this.isLoading = isLoading;
}
@ -204,18 +187,13 @@ public class SearchDepictionsFragment extends CommonsDaggerSupportFragment imple
ViewUtil.showShortSnackbar(depictionsRecyclerView, R.string.error_loading_depictions);
}
@Override
public RVRendererAdapter<DepictedItem> getAdapter() {
return depictionsAdapter;
}
/**
* Inform the view that there are no more items to be loaded for this search query
* or reset the isLastPage for the current query
* @param isLastPage
*/
@Override
public void setIsLastPage(boolean isLastPage) {
public void setIsLastPage(final boolean isLastPage) {
this.isLastPage=isLastPage;
progressBar.setVisibility(GONE);
}

View file

@ -1,11 +1,8 @@
package fr.free.nrw.commons.explore.depictions;
import com.pedrogomez.renderers.RVRendererAdapter;
import java.util.List;
import fr.free.nrw.commons.BasePresenter;
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
import java.util.List;
/**
* The contract with with SearchDepictionsFragment and its presenter would talk to each other
@ -44,11 +41,6 @@ public interface SearchDepictionsFragmentContract {
*/
void showSnackbar();
/**
* @return adapter
*/
RVRendererAdapter<DepictedItem> getAdapter();
/**
* Inform the view that there are no more items to be loaded for this search query
* or reset the isLastPage for the current query

View file

@ -1,112 +0,0 @@
package fr.free.nrw.commons.explore.depictions;
import android.graphics.Bitmap;
import android.net.Uri;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.Nullable;
import butterknife.BindView;
import butterknife.ButterKnife;
import com.facebook.common.executors.CallerThreadExecutor;
import com.facebook.common.references.CloseableReference;
import com.facebook.datasource.DataSource;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.imagepipeline.core.ImagePipeline;
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
import com.facebook.imagepipeline.image.CloseableImage;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;
import com.pedrogomez.renderers.Renderer;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
/**
* Renderer for DepictedItem
*/
public class SearchDepictionsRenderer extends Renderer<DepictedItem> {
@BindView(R.id.depicts_label)
TextView tvDepictionLabel;
@BindView(R.id.description)
TextView tvDepictionDesc;
@BindView(R.id.depicts_image)
ImageView imageView;
private DepictCallback listener;
public SearchDepictionsRenderer(DepictCallback listener) {
this.listener = listener;
}
@Override
protected void setUpView(View rootView) {
ButterKnife.bind(this, rootView);
}
@Override
protected void hookListeners(View rootView) {
rootView.setOnClickListener(v -> {
DepictedItem item = getContent();
if (listener != null) {
listener.depictsClicked(item);
}
});
}
@Override
protected View inflate(LayoutInflater inflater, ViewGroup parent) {
return inflater.inflate(R.layout.item_depictions, parent, false);
}
/**
* Render value to all the items in the search depictions list
*/
@Override
public void render() {
DepictedItem item = getContent();
tvDepictionLabel.setText(item.getName());
tvDepictionDesc.setText(item.getDescription());
imageView.setImageDrawable(getContext().getResources().getDrawable(R.drawable.ic_wikidata_logo_24dp));
if (!TextUtils.isEmpty(item.getImageUrl())) {
ImageRequest imageRequest = ImageRequestBuilder
.newBuilderWithSource(Uri.parse(item.getImageUrl()))
.setAutoRotateEnabled(true)
.build();
ImagePipeline imagePipeline = Fresco.getImagePipeline();
final DataSource<CloseableReference<CloseableImage>>
dataSource = imagePipeline.fetchDecodedImage(imageRequest, getContext());
dataSource.subscribe(new BaseBitmapDataSubscriber() {
@Override
public void onNewResultImpl(@Nullable Bitmap bitmap) {
if (dataSource.isFinished() && bitmap != null) {
//imageView.setImageBitmap(Bitmap.createBitmap(bitmap));
imageView.post(() -> imageView.setImageBitmap(Bitmap.createBitmap(bitmap)));
dataSource.close();
}
}
@Override
public void onFailureImpl(DataSource dataSource) {
if (dataSource != null) {
dataSource.close();
}
}
}, CallerThreadExecutor.getInstance());
}
}
public interface DepictCallback {
void depictsClicked(DepictedItem item);
}
}

View file

@ -5,12 +5,12 @@
android:layout_height="wrap_content"
android:padding="@dimen/tiny_gap">
<ImageView
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/depicts_image"
android:layout_width="70dp"
android:layout_height="70dp"
android:paddingRight="@dimen/tiny_gap"
app:srcCompat="@drawable/ic_wikidata_logo_24dp"
app:placeholderImage="@drawable/ic_wikidata_logo_24dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
@ -34,4 +34,4 @@
app:layout_constraintLeft_toRightOf="@+id/depicts_image"
app:layout_constraintTop_toBottomOf="@+id/depicts_label" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -23,6 +23,7 @@ DAGGER_VERSION=2.21
ROOM_VERSION=2.2.3
PREFERENCE_VERSION=1.1.0
CORE_KTX_VERSION=1.2.0
ADAPTER_DELEGATES_VERSION=4.3.0
systemProp.http.proxyPort=0
systemProp.http.proxyHost=