Merge branch 'even-more-ui-fixes' into 'master'
Even more ui fixes Closes #931 See merge request !471
This commit is contained in:
commit
46adf47fdf
@ -369,6 +369,11 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
initiateInstall(apk);
|
initiateInstall(apk);
|
||||||
|
|
||||||
|
// Scroll back to the header, so that the user can see the progress beginning. This can be
|
||||||
|
// removed once https://gitlab.com/fdroid/fdroidclient/issues/903 is implemented. However
|
||||||
|
// for now it adds valuable feedback to the user about the download they just initiated.
|
||||||
|
((LinearLayoutManager) recyclerView.getLayoutManager()).scrollToPositionWithOffset(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initiateInstall(Apk apk) {
|
private void initiateInstall(Apk apk) {
|
||||||
|
@ -432,8 +432,12 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
|||||||
Set<String> locales, String key) {
|
Set<String> locales, String key) {
|
||||||
try {
|
try {
|
||||||
for (String locale : locales) {
|
for (String locale : locales) {
|
||||||
if (localized.containsKey(locale)) {
|
Map<String, Object> entry = localized.get(locale);
|
||||||
return locale + "/" + localized.get(locale).get(key);
|
if (entry != null) {
|
||||||
|
Object value = entry.get(key);
|
||||||
|
if (value != null && value.toString().length() > 0) {
|
||||||
|
return locale + "/" + value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (ClassCastException e) {
|
} catch (ClassCastException e) {
|
||||||
|
@ -14,6 +14,7 @@ import android.os.Build;
|
|||||||
import android.support.annotation.ColorInt;
|
import android.support.annotation.ColorInt;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.support.v7.graphics.Palette;
|
import android.support.v7.graphics.Palette;
|
||||||
import android.support.v7.widget.AppCompatImageView;
|
import android.support.v7.widget.AppCompatImageView;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@ -25,6 +26,8 @@ import com.nostra13.universalimageloader.core.ImageLoader;
|
|||||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||||
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
||||||
|
|
||||||
|
import org.fdroid.fdroid.R;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,23 +61,34 @@ public class FeatureImage extends AppCompatImageView {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private Paint[] trianglePaints;
|
private Paint[] trianglePaints;
|
||||||
|
|
||||||
private static final Paint WHITE_PAINT = new Paint();
|
/**
|
||||||
|
* F-Droid blue is shown behind the animation which eases in the feature graphics. This is
|
||||||
static {
|
* preferable to showing white behind, which can be a bit harsh.
|
||||||
WHITE_PAINT.setColor(Color.WHITE);
|
*/
|
||||||
WHITE_PAINT.setStyle(Paint.Style.FILL);
|
@ColorInt
|
||||||
}
|
private int baseColour;
|
||||||
|
|
||||||
public FeatureImage(Context context) {
|
public FeatureImage(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
|
init(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeatureImage(Context context, @Nullable AttributeSet attrs) {
|
public FeatureImage(Context context, @Nullable AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
|
init(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeatureImage(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
public FeatureImage(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||||
super(context, attrs, defStyleAttr);
|
super(context, attrs, defStyleAttr);
|
||||||
|
init(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(Context context) {
|
||||||
|
float[] hsv = new float[3];
|
||||||
|
Color.colorToHSV(ContextCompat.getColor(context, R.color.fdroid_blue), hsv);
|
||||||
|
hsv[1] *= 0.5f;
|
||||||
|
hsv[2] *= 0.7f;
|
||||||
|
baseColour = Color.HSVToColor(hsv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -118,7 +132,10 @@ public class FeatureImage extends AppCompatImageView {
|
|||||||
for (int i = 0; i < trianglePaints.length; i++) {
|
for (int i = 0; i < trianglePaints.length; i++) {
|
||||||
trianglePaints[i] = random.nextBoolean() ? paintOne : paintTwo;
|
trianglePaints[i] = random.nextBoolean() ? paintOne : paintTwo;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColorAndAnimateChange(@ColorInt int colour) {
|
||||||
|
setColour(colour);
|
||||||
animateColourChange();
|
animateColourChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,6 +227,7 @@ public class FeatureImage extends AppCompatImageView {
|
|||||||
paint.setAlpha(currentAlpha);
|
paint.setAlpha(currentAlpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
canvas.drawColor(baseColour);
|
||||||
for (int i = 0; i < triangles.length; i++) {
|
for (int i = 0; i < triangles.length; i++) {
|
||||||
canvas.drawPath(triangles[i], trianglePaints[i]);
|
canvas.drawPath(triangles[i], trianglePaints[i]);
|
||||||
}
|
}
|
||||||
@ -236,6 +254,7 @@ public class FeatureImage extends AppCompatImageView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void loadImageAndDisplay(@NonNull ImageLoader loader, @NonNull DisplayImageOptions imageOptions, @Nullable String featureImageToShow, @Nullable String fallbackImageToExtractColours) {
|
public void loadImageAndDisplay(@NonNull ImageLoader loader, @NonNull DisplayImageOptions imageOptions, @Nullable String featureImageToShow, @Nullable String fallbackImageToExtractColours) {
|
||||||
|
setColour(ContextCompat.getColor(getContext(), R.color.fdroid_blue));
|
||||||
if (!TextUtils.isEmpty(featureImageToShow)) {
|
if (!TextUtils.isEmpty(featureImageToShow)) {
|
||||||
loadImageAndDisplay(loader, imageOptions, featureImageToShow);
|
loadImageAndDisplay(loader, imageOptions, featureImageToShow);
|
||||||
} else if (!TextUtils.isEmpty(fallbackImageToExtractColours)) {
|
} else if (!TextUtils.isEmpty(fallbackImageToExtractColours)) {
|
||||||
@ -252,7 +271,7 @@ public class FeatureImage extends AppCompatImageView {
|
|||||||
@Override
|
@Override
|
||||||
public void onGenerated(Palette palette) {
|
public void onGenerated(Palette palette) {
|
||||||
if (palette != null) {
|
if (palette != null) {
|
||||||
setColour(palette.getDominantColor(Color.LTGRAY));
|
setColorAndAnimateChange(palette.getDominantColor(Color.LTGRAY));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -10,6 +10,7 @@ import android.support.annotation.IdRes;
|
|||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.app.ActivityOptionsCompat;
|
import android.support.v4.app.ActivityOptionsCompat;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.support.v4.util.Pair;
|
import android.support.v4.util.Pair;
|
||||||
import android.support.v7.graphics.Palette;
|
import android.support.v7.graphics.Palette;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
@ -120,7 +121,7 @@ public class AppCardController extends RecyclerView.ViewHolder implements ImageL
|
|||||||
ImageLoader.getInstance().displayImage(app.iconUrl, icon, displayImageOptions, this);
|
ImageLoader.getInstance().displayImage(app.iconUrl, icon, displayImageOptions, this);
|
||||||
|
|
||||||
if (featuredImage != null) {
|
if (featuredImage != null) {
|
||||||
featuredImage.setColour(0);
|
featuredImage.setColour(ContextCompat.getColor(activity, R.color.fdroid_blue));
|
||||||
featuredImage.setImageDrawable(null);
|
featuredImage.setImageDrawable(null);
|
||||||
|
|
||||||
// Note: We could call the convenience function loadImageAndDisplay(ImageLoader, DisplayImageOptions, String, String)
|
// Note: We could call the convenience function loadImageAndDisplay(ImageLoader, DisplayImageOptions, String, String)
|
||||||
@ -183,7 +184,7 @@ public class AppCardController extends RecyclerView.ViewHolder implements ImageL
|
|||||||
new Palette.Builder(loadedImage).generate(new Palette.PaletteAsyncListener() {
|
new Palette.Builder(loadedImage).generate(new Palette.PaletteAsyncListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onGenerated(Palette palette) {
|
public void onGenerated(Palette palette) {
|
||||||
featuredImage.setColour(palette.getDominantColor(Color.LTGRAY));
|
featuredImage.setColorAndAnimateChange(palette.getDominantColor(Color.LTGRAY));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ public class CategoryController extends RecyclerView.ViewHolder implements Loade
|
|||||||
image.setColour(backgroundColour);
|
image.setColour(backgroundColour);
|
||||||
image.setImageDrawable(null);
|
image.setImageDrawable(null);
|
||||||
} else {
|
} else {
|
||||||
image.setColour(0);
|
image.setColour(ContextCompat.getColor(activity, R.color.fdroid_blue));
|
||||||
ImageLoader.getInstance().displayImage("drawable://" + categoryImageId, image, displayImageOptions);
|
ImageLoader.getInstance().displayImage("drawable://" + categoryImageId, image, displayImageOptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ import android.support.v7.widget.RecyclerView;
|
|||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.fdroid.fdroid.FDroidApp;
|
import org.fdroid.fdroid.FDroidApp;
|
||||||
import org.fdroid.fdroid.R;
|
import org.fdroid.fdroid.R;
|
||||||
@ -43,6 +44,8 @@ import org.fdroid.fdroid.views.apps.AppListItemController;
|
|||||||
public class InstalledAppsActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {
|
public class InstalledAppsActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {
|
||||||
|
|
||||||
private InstalledAppListAdapter adapter;
|
private InstalledAppListAdapter adapter;
|
||||||
|
private RecyclerView appList;
|
||||||
|
private TextView emptyState;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@ -59,10 +62,12 @@ public class InstalledAppsActivity extends AppCompatActivity implements LoaderMa
|
|||||||
|
|
||||||
adapter = new InstalledAppListAdapter(this);
|
adapter = new InstalledAppListAdapter(this);
|
||||||
|
|
||||||
RecyclerView appList = (RecyclerView) findViewById(R.id.app_list);
|
appList = (RecyclerView) findViewById(R.id.app_list);
|
||||||
appList.setHasFixedSize(true);
|
appList.setHasFixedSize(true);
|
||||||
appList.setLayoutManager(new LinearLayoutManager(this));
|
appList.setLayoutManager(new LinearLayoutManager(this));
|
||||||
appList.setAdapter(adapter);
|
appList.setAdapter(adapter);
|
||||||
|
|
||||||
|
emptyState = (TextView) findViewById(R.id.empty_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -85,6 +90,14 @@ public class InstalledAppsActivity extends AppCompatActivity implements LoaderMa
|
|||||||
@Override
|
@Override
|
||||||
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
|
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
|
||||||
adapter.setApps(cursor);
|
adapter.setApps(cursor);
|
||||||
|
|
||||||
|
if (adapter.getItemCount() == 0) {
|
||||||
|
appList.setVisibility(View.GONE);
|
||||||
|
emptyState.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
appList.setVisibility(View.VISIBLE);
|
||||||
|
emptyState.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -5,22 +5,28 @@ import android.support.v7.widget.LinearLayoutManager;
|
|||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.fdroid.fdroid.R;
|
import org.fdroid.fdroid.R;
|
||||||
|
|
||||||
public class UpdatesViewBinder {
|
public class UpdatesViewBinder {
|
||||||
|
|
||||||
private final UpdatesAdapter adapter;
|
private final UpdatesAdapter adapter;
|
||||||
|
private final RecyclerView list;
|
||||||
|
private final TextView emptyState;
|
||||||
|
|
||||||
public UpdatesViewBinder(AppCompatActivity activity, FrameLayout parent) {
|
public UpdatesViewBinder(AppCompatActivity activity, FrameLayout parent) {
|
||||||
View view = activity.getLayoutInflater().inflate(R.layout.main_tab_updates, parent, true);
|
View view = activity.getLayoutInflater().inflate(R.layout.main_tab_updates, parent, true);
|
||||||
|
|
||||||
adapter = new UpdatesAdapter(activity);
|
adapter = new UpdatesAdapter(activity);
|
||||||
|
adapter.registerAdapterDataObserver(adapterChangeListener);
|
||||||
|
|
||||||
RecyclerView list = (RecyclerView) view.findViewById(R.id.list);
|
list = (RecyclerView) view.findViewById(R.id.list);
|
||||||
list.setHasFixedSize(true);
|
list.setHasFixedSize(true);
|
||||||
list.setLayoutManager(new LinearLayoutManager(activity));
|
list.setLayoutManager(new LinearLayoutManager(activity));
|
||||||
list.setAdapter(adapter);
|
list.setAdapter(adapter);
|
||||||
|
|
||||||
|
emptyState = (TextView) view.findViewById(R.id.empty_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind() {
|
public void bind() {
|
||||||
@ -30,4 +36,32 @@ public class UpdatesViewBinder {
|
|||||||
public void unbind() {
|
public void unbind() {
|
||||||
adapter.stopListeningForStatusUpdates();
|
adapter.stopListeningForStatusUpdates();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateEmptyState() {
|
||||||
|
if (adapter.getItemCount() == 0) {
|
||||||
|
list.setVisibility(View.GONE);
|
||||||
|
emptyState.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
list.setVisibility(View.VISIBLE);
|
||||||
|
emptyState.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("FieldCanBeLocal")
|
||||||
|
private final RecyclerView.AdapterDataObserver adapterChangeListener = new RecyclerView.AdapterDataObserver() {
|
||||||
|
@Override
|
||||||
|
public void onChanged() {
|
||||||
|
updateEmptyState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemRangeInserted(int positionStart, int itemCount) {
|
||||||
|
updateEmptyState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemRangeRemoved(int positionStart, int itemCount) {
|
||||||
|
updateEmptyState();
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
android:paddingBottom="5dp"
|
android:paddingBottom="5dp"
|
||||||
android:paddingLeft="10dp"
|
android:paddingLeft="10dp"
|
||||||
android:paddingRight="10dp"
|
android:paddingRight="10dp"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
>
|
>
|
||||||
|
|
||||||
<TextView android:id="@+id/version"
|
<TextView android:id="@+id/version"
|
||||||
|
@ -36,7 +36,6 @@
|
|||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="@+id/header_height"
|
app:layout_constraintTop_toTopOf="@+id/header_height"
|
||||||
android:foreground="?attr/selectableItemBackground"
|
android:foreground="?attr/selectableItemBackground"
|
||||||
android:clickable="true"
|
|
||||||
>
|
>
|
||||||
|
|
||||||
<android.support.constraint.ConstraintLayout
|
<android.support.constraint.ConstraintLayout
|
||||||
|
@ -16,6 +16,18 @@
|
|||||||
app:theme="?attr/actionBarTheme"
|
app:theme="?attr/actionBarTheme"
|
||||||
app:popupTheme="?attr/actionBarPopupTheme" />
|
app:popupTheme="?attr/actionBarPopupTheme" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/empty_state"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/toolbar"
|
||||||
|
style="@style/AppListEmptyText"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:text="@string/empty_installed_app_list" />
|
||||||
|
|
||||||
<android.support.v7.widget.RecyclerView
|
<android.support.v7.widget.RecyclerView
|
||||||
android:id="@+id/app_list"
|
android:id="@+id/app_list"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
@ -5,6 +5,14 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/empty_state"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
style="@style/AppListEmptyText"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:text="@string/empty_can_update_app_list" />
|
||||||
|
|
||||||
<android.support.v7.widget.RecyclerView
|
<android.support.v7.widget.RecyclerView
|
||||||
android:id="@+id/list"
|
android:id="@+id/list"
|
||||||
tools:listitem="@layout/app_list_item"
|
tools:listitem="@layout/app_list_item"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user