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; | ||||
|         } | ||||
|         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) { | ||||
|  | ||||
| @ -432,8 +432,12 @@ public class App extends ValueObject implements Comparable<App>, Parcelable { | ||||
|                                              Set<String> locales, String key) { | ||||
|         try { | ||||
|             for (String locale : locales) { | ||||
|                 if (localized.containsKey(locale)) { | ||||
|                     return locale + "/" + localized.get(locale).get(key); | ||||
|                 Map<String, Object> entry = localized.get(locale); | ||||
|                 if (entry != null) { | ||||
|                     Object value = entry.get(key); | ||||
|                     if (value != null && value.toString().length() > 0) { | ||||
|                         return locale + "/" + value; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } catch (ClassCastException e) { | ||||
|  | ||||
| @ -14,6 +14,7 @@ import android.os.Build; | ||||
| import android.support.annotation.ColorInt; | ||||
| import android.support.annotation.NonNull; | ||||
| import android.support.annotation.Nullable; | ||||
| import android.support.v4.content.ContextCompat; | ||||
| import android.support.v7.graphics.Palette; | ||||
| import android.support.v7.widget.AppCompatImageView; | ||||
| 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.listener.ImageLoadingListener; | ||||
| 
 | ||||
| import org.fdroid.fdroid.R; | ||||
| 
 | ||||
| import java.util.Random; | ||||
| 
 | ||||
| /** | ||||
| @ -58,23 +61,34 @@ public class FeatureImage extends AppCompatImageView { | ||||
|     @Nullable | ||||
|     private Paint[] trianglePaints; | ||||
| 
 | ||||
|     private static final Paint WHITE_PAINT = new Paint(); | ||||
| 
 | ||||
|     static { | ||||
|         WHITE_PAINT.setColor(Color.WHITE); | ||||
|         WHITE_PAINT.setStyle(Paint.Style.FILL); | ||||
|     } | ||||
|     /** | ||||
|      * F-Droid blue is shown behind the animation which eases in the feature graphics. This is | ||||
|      * preferable to showing white behind, which can be a bit harsh. | ||||
|      */ | ||||
|     @ColorInt | ||||
|     private int baseColour; | ||||
| 
 | ||||
|     public FeatureImage(Context context) { | ||||
|         super(context); | ||||
|         init(context); | ||||
|     } | ||||
| 
 | ||||
|     public FeatureImage(Context context, @Nullable AttributeSet attrs) { | ||||
|         super(context, attrs); | ||||
|         init(context); | ||||
|     } | ||||
| 
 | ||||
|     public FeatureImage(Context context, @Nullable AttributeSet attrs, int 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++) { | ||||
|             trianglePaints[i] = random.nextBoolean() ? paintOne : paintTwo; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public void setColorAndAnimateChange(@ColorInt int colour) { | ||||
|         setColour(colour); | ||||
|         animateColourChange(); | ||||
|     } | ||||
| 
 | ||||
| @ -210,6 +227,7 @@ public class FeatureImage extends AppCompatImageView { | ||||
|                 paint.setAlpha(currentAlpha); | ||||
|             } | ||||
| 
 | ||||
|             canvas.drawColor(baseColour); | ||||
|             for (int i = 0; i < triangles.length; 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) { | ||||
|         setColour(ContextCompat.getColor(getContext(), R.color.fdroid_blue)); | ||||
|         if (!TextUtils.isEmpty(featureImageToShow)) { | ||||
|             loadImageAndDisplay(loader, imageOptions, featureImageToShow); | ||||
|         } else if (!TextUtils.isEmpty(fallbackImageToExtractColours)) { | ||||
| @ -252,7 +271,7 @@ public class FeatureImage extends AppCompatImageView { | ||||
|                         @Override | ||||
|                         public void onGenerated(Palette palette) { | ||||
|                             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.Nullable; | ||||
| import android.support.v4.app.ActivityOptionsCompat; | ||||
| import android.support.v4.content.ContextCompat; | ||||
| import android.support.v4.util.Pair; | ||||
| import android.support.v7.graphics.Palette; | ||||
| 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); | ||||
| 
 | ||||
|         if (featuredImage != null) { | ||||
|             featuredImage.setColour(0); | ||||
|             featuredImage.setColour(ContextCompat.getColor(activity, R.color.fdroid_blue)); | ||||
|             featuredImage.setImageDrawable(null); | ||||
| 
 | ||||
|             // 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() { | ||||
|                 @Override | ||||
|                 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.setImageDrawable(null); | ||||
|         } else { | ||||
|             image.setColour(0); | ||||
|             image.setColour(ContextCompat.getColor(activity, R.color.fdroid_blue)); | ||||
|             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.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.TextView; | ||||
| 
 | ||||
| import org.fdroid.fdroid.FDroidApp; | ||||
| 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> { | ||||
| 
 | ||||
|     private InstalledAppListAdapter adapter; | ||||
|     private RecyclerView appList; | ||||
|     private TextView emptyState; | ||||
| 
 | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
| @ -59,10 +62,12 @@ public class InstalledAppsActivity extends AppCompatActivity implements LoaderMa | ||||
| 
 | ||||
|         adapter = new InstalledAppListAdapter(this); | ||||
| 
 | ||||
|         RecyclerView appList = (RecyclerView) findViewById(R.id.app_list); | ||||
|         appList = (RecyclerView) findViewById(R.id.app_list); | ||||
|         appList.setHasFixedSize(true); | ||||
|         appList.setLayoutManager(new LinearLayoutManager(this)); | ||||
|         appList.setAdapter(adapter); | ||||
| 
 | ||||
|         emptyState = (TextView) findViewById(R.id.empty_state); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
| @ -85,6 +90,14 @@ public class InstalledAppsActivity extends AppCompatActivity implements LoaderMa | ||||
|     @Override | ||||
|     public void onLoadFinished(Loader<Cursor> loader, Cursor 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 | ||||
|  | ||||
| @ -5,22 +5,28 @@ import android.support.v7.widget.LinearLayoutManager; | ||||
| import android.support.v7.widget.RecyclerView; | ||||
| import android.view.View; | ||||
| import android.widget.FrameLayout; | ||||
| import android.widget.TextView; | ||||
| 
 | ||||
| import org.fdroid.fdroid.R; | ||||
| 
 | ||||
| public class UpdatesViewBinder { | ||||
| 
 | ||||
|     private final UpdatesAdapter adapter; | ||||
|     private final RecyclerView list; | ||||
|     private final TextView emptyState; | ||||
| 
 | ||||
|     public UpdatesViewBinder(AppCompatActivity activity, FrameLayout parent) { | ||||
|         View view = activity.getLayoutInflater().inflate(R.layout.main_tab_updates, parent, true); | ||||
| 
 | ||||
|         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.setLayoutManager(new LinearLayoutManager(activity)); | ||||
|         list.setAdapter(adapter); | ||||
| 
 | ||||
|         emptyState = (TextView) view.findViewById(R.id.empty_state); | ||||
|     } | ||||
| 
 | ||||
|     public void bind() { | ||||
| @ -30,4 +36,32 @@ public class UpdatesViewBinder { | ||||
|     public void unbind() { | ||||
|         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:paddingLeft="10dp" | ||||
|         android:paddingRight="10dp" | ||||
|         android:background="?attr/selectableItemBackground" | ||||
|         > | ||||
| 
 | ||||
|       <TextView android:id="@+id/version" | ||||
|  | ||||
| @ -36,7 +36,6 @@ | ||||
|         app:layout_constraintEnd_toEndOf="parent" | ||||
|         app:layout_constraintTop_toTopOf="@+id/header_height" | ||||
|         android:foreground="?attr/selectableItemBackground" | ||||
|         android:clickable="true" | ||||
|         > | ||||
| 
 | ||||
|         <android.support.constraint.ConstraintLayout | ||||
|  | ||||
| @ -16,6 +16,18 @@ | ||||
|         app:theme="?attr/actionBarTheme" | ||||
|         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:id="@+id/app_list" | ||||
|         android:layout_width="0dp" | ||||
|  | ||||
| @ -5,6 +5,14 @@ | ||||
|     android:layout_width="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:id="@+id/list" | ||||
|         tools:listitem="@layout/app_list_item" | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Hans-Christoph Steiner
						Hans-Christoph Steiner