Initial work on details view
This commit is contained in:
		
							parent
							
								
									f355232bd5
								
							
						
					
					
						commit
						34450569b3
					
				| @ -404,6 +404,17 @@ | ||||
|                 android:value=".FDroid" /> | ||||
| 
 | ||||
|         </activity> | ||||
|         <activity | ||||
|             android:name=".AppDetails2" | ||||
|             android:label="@string/app_details" | ||||
|             android:exported="true" | ||||
|             android:parentActivityName=".FDroid" | ||||
|             android:theme="@style/AppThemeLight.NoActionBar" | ||||
|             android:configChanges="layoutDirection|locale" > | ||||
|             <meta-data | ||||
|                 android:name="android.support.PARENT_ACTIVITY" | ||||
|                 android:value=".FDroid" /> | ||||
|         </activity> | ||||
|         <activity | ||||
|             android:label="@string/menu_settings" | ||||
|             android:name=".PreferencesActivity" | ||||
|  | ||||
							
								
								
									
										500
									
								
								app/src/main/java/org/fdroid/fdroid/AppDetails2.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										500
									
								
								app/src/main/java/org/fdroid/fdroid/AppDetails2.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,500 @@ | ||||
| package org.fdroid.fdroid; | ||||
| 
 | ||||
| import android.content.ActivityNotFoundException; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.graphics.Bitmap; | ||||
| import android.os.Bundle; | ||||
| import android.support.annotation.NonNull; | ||||
| import android.support.v4.view.ViewCompat; | ||||
| import android.support.v4.widget.TextViewCompat; | ||||
| import android.support.v7.app.AppCompatActivity; | ||||
| import android.support.v7.text.AllCapsTransformationMethod; | ||||
| import android.support.v7.widget.LinearLayoutManager; | ||||
| import android.support.v7.widget.RecyclerView; | ||||
| import android.support.v7.widget.Toolbar; | ||||
| import android.text.Html; | ||||
| import android.text.Layout; | ||||
| import android.text.Selection; | ||||
| import android.text.Spannable; | ||||
| import android.text.Spanned; | ||||
| import android.text.TextUtils; | ||||
| import android.text.method.LinkMovementMethod; | ||||
| import android.text.style.ClickableSpan; | ||||
| import android.util.Log; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.MotionEvent; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.Button; | ||||
| import android.widget.ImageView; | ||||
| import android.widget.TextView; | ||||
| import android.widget.Toast; | ||||
| 
 | ||||
| import com.nostra13.universalimageloader.core.DisplayImageOptions; | ||||
| import com.nostra13.universalimageloader.core.ImageLoader; | ||||
| import com.nostra13.universalimageloader.core.assist.ImageScaleType; | ||||
| 
 | ||||
| import org.fdroid.fdroid.data.App; | ||||
| import org.fdroid.fdroid.data.AppProvider; | ||||
| import org.fdroid.fdroid.views.LinearLayoutManagerSnapHelper; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| import static android.support.v7.widget.RecyclerView.NO_POSITION; | ||||
| 
 | ||||
| public class AppDetails2 extends AppCompatActivity { | ||||
| 
 | ||||
|     private static final String TAG = "AppDetails2"; | ||||
| 
 | ||||
|     private App mApp; | ||||
|     private RecyclerView mRecyclerView; | ||||
|     private AppDetailsRecyclerViewAdapter mAdapter; | ||||
| 
 | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
|         super.onCreate(savedInstanceState); | ||||
|         setContentView(R.layout.activity_app_details2); | ||||
|         Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); | ||||
|         toolbar.setTitle(""); // Nice and clean toolbar | ||||
|         setSupportActionBar(toolbar); | ||||
|         getSupportActionBar().setDisplayHomeAsUpEnabled(true); | ||||
| 
 | ||||
|         App app = null; | ||||
|         String packageName = getPackageNameFromIntent(getIntent()); | ||||
|         if (!TextUtils.isEmpty(packageName)) { | ||||
|             app = AppProvider.Helper.findHighestPriorityMetadata(getContentResolver(), packageName); | ||||
|         } | ||||
|         setApp(app); // Will call finish if empty or unknown | ||||
| 
 | ||||
|         mRecyclerView = (RecyclerView) findViewById(R.id.rvDetails); | ||||
|         mAdapter = new AppDetailsRecyclerViewAdapter(this); | ||||
|         LinearLayoutManager lm = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false); | ||||
|         lm.setStackFromEnd(false); | ||||
|         mRecyclerView.setLayoutManager(lm); | ||||
|         mRecyclerView.setAdapter(mAdapter); | ||||
|     } | ||||
| 
 | ||||
|     private String getPackageNameFromIntent(Intent intent) { | ||||
|         if (!intent.hasExtra(AppDetails.EXTRA_APPID)) { | ||||
|             Log.e(TAG, "No package name found in the intent!"); | ||||
|             return null; | ||||
|         } | ||||
|         return intent.getStringExtra(AppDetails.EXTRA_APPID); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * If passed null, this will show a message to the user ("Could not find app ..." or something | ||||
|      * like that) and then finish the activity. | ||||
|      */ | ||||
|     private void setApp(App newApp) { | ||||
|         if (newApp == null) { | ||||
|             Toast.makeText(this, R.string.no_such_app, Toast.LENGTH_LONG).show(); | ||||
|             finish(); | ||||
|             return; | ||||
|         } | ||||
|         mApp = newApp; | ||||
|     } | ||||
| 
 | ||||
|     public class AppDetailsRecyclerViewAdapter | ||||
|             extends RecyclerView.Adapter<RecyclerView.ViewHolder> { | ||||
| 
 | ||||
|         private final int VIEWTYPE_HEADER = 0; | ||||
|         private final int VIEWTYPE_SCREENSHOTS = 1; | ||||
|         private final int VIEWTYPE_WHATS_NEW = 2; | ||||
| 
 | ||||
|         private final Context mContext; | ||||
|         private ArrayList<Integer> mItems; | ||||
| 
 | ||||
|         public AppDetailsRecyclerViewAdapter(Context context) { | ||||
|             mContext = context; | ||||
|             updateItems(); | ||||
|         } | ||||
| 
 | ||||
|         private void updateItems() { | ||||
|             if (mItems == null) | ||||
|                 mItems = new ArrayList<>(); | ||||
|             else | ||||
|                 mItems.clear(); | ||||
|             mItems.add(Integer.valueOf(VIEWTYPE_HEADER)); | ||||
|             mItems.add(Integer.valueOf(VIEWTYPE_SCREENSHOTS)); | ||||
|             mItems.add(Integer.valueOf(VIEWTYPE_WHATS_NEW)); | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { | ||||
|             if (viewType == VIEWTYPE_HEADER) { | ||||
|                 View view = LayoutInflater.from(parent.getContext()) | ||||
|                         .inflate(R.layout.app_details2_header, parent, false); | ||||
|                 return new HeaderViewHolder(view); | ||||
|             } else if (viewType == VIEWTYPE_SCREENSHOTS) { | ||||
|                 View view = LayoutInflater.from(parent.getContext()) | ||||
|                         .inflate(R.layout.app_details2_screenshots, parent, false); | ||||
|                 return new ScreenShotsViewHolder(view); | ||||
|             } else if (viewType == VIEWTYPE_WHATS_NEW) { | ||||
|                 View view = LayoutInflater.from(parent.getContext()) | ||||
|                         .inflate(R.layout.app_details2_whatsnew, parent, false); | ||||
|                 return new WhatsNewViewHolder(view); | ||||
|             } | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) { | ||||
|             int viewType = mItems.get(position); | ||||
|             if (viewType == VIEWTYPE_HEADER) { | ||||
|                 final HeaderViewHolder vh = (HeaderViewHolder) holder; | ||||
|                 ImageLoader.getInstance().displayImage(mApp.iconUrlLarge, vh.iconView, vh.displayImageOptions); | ||||
|                 vh.titleView.setText(mApp.name); | ||||
|                 if (!TextUtils.isEmpty(mApp.author)) { | ||||
|                     vh.authorView.setText(getString(R.string.by_author) + " " + mApp.author); | ||||
|                     vh.authorView.setVisibility(View.VISIBLE); | ||||
|                 } else { | ||||
|                     vh.authorView.setVisibility(View.GONE); | ||||
|                 } | ||||
|                 vh.summaryView.setText(mApp.summary); | ||||
|                 final Spanned desc = Html.fromHtml(mApp.description, null, new Utils.HtmlTagHandler()); | ||||
|                 vh.descriptionView.setMovementMethod(AppDetails2.SafeLinkMovementMethod.getInstance(mContext)); | ||||
|                 vh.descriptionView.setText(trimNewlines(desc)); | ||||
|                 vh.descriptionView.post(new Runnable() { | ||||
|                     @Override | ||||
|                     public void run() { | ||||
|                         if (vh.descriptionView.getLineCount() < HeaderViewHolder.MAX_LINES) { | ||||
|                             vh.descriptionMoreView.setVisibility(View.GONE); | ||||
|                         } else { | ||||
|                             vh.descriptionMoreView.setVisibility(View.VISIBLE); | ||||
|                         } | ||||
|                     } | ||||
|                 }); | ||||
|                 vh.buttonSecondaryView.setText(R.string.menu_uninstall); | ||||
|                 vh.buttonSecondaryView.setVisibility(mApp.isInstalled() ? View.VISIBLE : View.INVISIBLE); | ||||
|                 vh.buttonPrimaryView.setText(R.string.menu_install); | ||||
|                 vh.buttonPrimaryView.setVisibility(View.VISIBLE); | ||||
| 
 | ||||
| /*                if (appDetails.activeDownloadUrlString != null) { | ||||
|                     btMain.setText(R.string.downloading); | ||||
|                     btMain.setEnabled(false); | ||||
|                 } else if (!app.isInstalled() && app.suggestedVersionCode > 0 && | ||||
|                         appDetails.adapter.getCount() > 0) { | ||||
|                     // Check count > 0 due to incompatible apps resulting in an empty list. | ||||
|                     // If App isn't installed | ||||
|                     installed = false; | ||||
|                     statusView.setText(R.string.details_notinstalled); | ||||
|                     NfcHelper.disableAndroidBeam(appDetails); | ||||
|                     // Set Install button and hide second button | ||||
|                     btMain.setText(R.string.menu_install); | ||||
|                     btMain.setOnClickListener(mOnClickListener); | ||||
|                     btMain.setEnabled(true); | ||||
|                 } else if (app.isInstalled()) { | ||||
|                     // If App is installed | ||||
|                     installed = true; | ||||
|                     statusView.setText(getString(R.string.details_installed, app.installedVersionName)); | ||||
|                     NfcHelper.setAndroidBeam(appDetails, app.packageName); | ||||
|                     if (app.canAndWantToUpdate(appDetails)) { | ||||
|                         updateWanted = true; | ||||
|                         btMain.setText(R.string.menu_upgrade); | ||||
|                     } else { | ||||
|                         updateWanted = false; | ||||
|                         if (appDetails.packageManager.getLaunchIntentForPackage(app.packageName) != null) { | ||||
|                             btMain.setText(R.string.menu_launch); | ||||
|                         } else { | ||||
|                             btMain.setText(R.string.menu_uninstall); | ||||
|                         } | ||||
|                     } | ||||
|                     btMain.setOnClickListener(mOnClickListener); | ||||
|                     btMain.setEnabled(true); | ||||
|                 } | ||||
| 
 | ||||
|                 TextView currentVersion = (TextView) view.findViewById(R.id.current_version); | ||||
|                 if (!appDetails.getApks().isEmpty()) { | ||||
|                     currentVersion.setText(appDetails.getApks().getItem(0).versionName + " (" + app.license + ")"); | ||||
|                 } else { | ||||
|                     currentVersion.setVisibility(View.GONE); | ||||
|                     btMain.setVisibility(View.GONE); | ||||
|                 }*/ | ||||
| 
 | ||||
|             } else if (viewType == VIEWTYPE_SCREENSHOTS) { | ||||
|                 ScreenShotsViewHolder vh = (ScreenShotsViewHolder) holder; | ||||
|                 LinearLayoutManager lm = new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false); | ||||
|                 vh.recyclerView.setLayoutManager(lm); | ||||
|                 ScreenShotsRecyclerViewAdapter adapter = new ScreenShotsRecyclerViewAdapter(mApp); | ||||
|                 vh.recyclerView.setAdapter(adapter); | ||||
|                 vh.recyclerView.setHasFixedSize(true); | ||||
|                 vh.recyclerView.setNestedScrollingEnabled(false); | ||||
|                 LinearLayoutManagerSnapHelper helper = new LinearLayoutManagerSnapHelper(lm); | ||||
|                 helper.setLinearSnapHelperListener(adapter); | ||||
|                 helper.attachToRecyclerView(vh.recyclerView); | ||||
|             } else if (viewType == VIEWTYPE_WHATS_NEW) { | ||||
|                 WhatsNewViewHolder vh = (WhatsNewViewHolder) holder; | ||||
|                 vh.textView.setText("WHATS NEW GOES HERE"); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public int getItemCount() { | ||||
|             return mItems.size(); | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public int getItemViewType(int position) { | ||||
|             return mItems.get(position); | ||||
|         } | ||||
| 
 | ||||
|         public class HeaderViewHolder extends RecyclerView.ViewHolder { | ||||
|             private static final int MAX_LINES = 5; | ||||
| 
 | ||||
|             final ImageView iconView; | ||||
|             final TextView titleView; | ||||
|             final TextView authorView; | ||||
|             final TextView summaryView; | ||||
|             final TextView descriptionView; | ||||
|             final TextView descriptionMoreView; | ||||
|             final Button buttonPrimaryView; | ||||
|             final Button buttonSecondaryView; | ||||
|             final DisplayImageOptions displayImageOptions; | ||||
| 
 | ||||
|             HeaderViewHolder(View view) { | ||||
|                 super(view); | ||||
|                 iconView = (ImageView) view.findViewById(R.id.icon); | ||||
|                 titleView = (TextView) view.findViewById(R.id.title); | ||||
|                 authorView = (TextView) view.findViewById(R.id.author); | ||||
|                 summaryView = (TextView) view.findViewById(R.id.summary); | ||||
|                 descriptionView = (TextView) view.findViewById(R.id.description); | ||||
|                 descriptionMoreView = (TextView) view.findViewById(R.id.description_more); | ||||
|                 buttonPrimaryView = (Button) view.findViewById(R.id.primaryButtonView); | ||||
|                 buttonSecondaryView = (Button) view.findViewById(R.id.secondaryButtonView); | ||||
|                 displayImageOptions = new DisplayImageOptions.Builder() | ||||
|                         .cacheInMemory(true) | ||||
|                         .cacheOnDisk(true) | ||||
|                         .imageScaleType(ImageScaleType.NONE) | ||||
|                         .showImageOnLoading(R.drawable.ic_repo_app_default) | ||||
|                         .showImageForEmptyUri(R.drawable.ic_repo_app_default) | ||||
|                         .bitmapConfig(Bitmap.Config.RGB_565) | ||||
|                         .build(); | ||||
|                 descriptionView.setMaxLines(MAX_LINES); | ||||
|                 descriptionView.setEllipsize(TextUtils.TruncateAt.MARQUEE); | ||||
|                 descriptionMoreView.setOnClickListener(new View.OnClickListener() { | ||||
|                     @Override | ||||
|                     public void onClick(View v) { | ||||
|                         // Remember current scroll position so that we can restore it | ||||
|                         LinearLayoutManager lm = (LinearLayoutManager)mRecyclerView.getLayoutManager(); | ||||
|                         int pos = lm.findFirstVisibleItemPosition(); | ||||
|                         int posOffset = 0; | ||||
|                         if (pos != NO_POSITION) { | ||||
|                             View view = lm.findViewByPosition(pos); | ||||
|                             if (view != null) | ||||
|                                 posOffset = lm.getDecoratedTop(view); | ||||
|                         } | ||||
|                         if (TextViewCompat.getMaxLines(descriptionView) != MAX_LINES) { | ||||
|                             descriptionView.setMaxLines(MAX_LINES); | ||||
|                             descriptionMoreView.setText(R.string.more); | ||||
|                         } else { | ||||
|                             descriptionView.setMaxLines(Integer.MAX_VALUE); | ||||
|                             descriptionMoreView.setText(R.string.less); | ||||
|                         } | ||||
|                         if (pos != NO_POSITION) { | ||||
|                             // Restore scroll position | ||||
|                             lm.scrollToPositionWithOffset(pos, posOffset); | ||||
|                         } | ||||
|                     } | ||||
|                 }); | ||||
|                 // Set ALL caps (in a way compatible with SDK 10) | ||||
|                 AllCapsTransformationMethod allCapsTransformation = new AllCapsTransformationMethod(view.getContext()); | ||||
|                 buttonPrimaryView.setTransformationMethod(allCapsTransformation); | ||||
|                 buttonSecondaryView.setTransformationMethod(allCapsTransformation); | ||||
|                 descriptionMoreView.setTransformationMethod(allCapsTransformation); | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public String toString() { | ||||
|                 return super.toString() + " '" + titleView.getText() + "'"; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public class ScreenShotsViewHolder extends RecyclerView.ViewHolder { | ||||
|             final RecyclerView recyclerView; | ||||
| 
 | ||||
|             ScreenShotsViewHolder(View view) { | ||||
|                 super(view); | ||||
|                 recyclerView = (RecyclerView) view.findViewById(R.id.screenshots); | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public String toString() { | ||||
|                 return super.toString() + " screenshots"; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public class WhatsNewViewHolder extends RecyclerView.ViewHolder { | ||||
|             final TextView textView; | ||||
| 
 | ||||
|             WhatsNewViewHolder(View view) { | ||||
|                 super(view); | ||||
|                 textView = (TextView) view.findViewById(R.id.text); | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public String toString() { | ||||
|                 return super.toString() + " " + textView.getText(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         class ScreenShotsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements LinearLayoutManagerSnapHelper.LinearSnapHelperListener { | ||||
|             private final App app; | ||||
|             private final DisplayImageOptions displayImageOptions; | ||||
|             private View selectedView; | ||||
|             private int selectedPosition; | ||||
|             private int selectedItemElevation; | ||||
|             private int unselectedItemMargin; | ||||
| 
 | ||||
|             public ScreenShotsRecyclerViewAdapter(App app) { | ||||
|                 super(); | ||||
|                 this.app = app; | ||||
|                 selectedPosition = 0; | ||||
|                 selectedItemElevation = getResources().getDimensionPixelSize(R.dimen.details_screenshot_selected_elevation); | ||||
|                 unselectedItemMargin = getResources().getDimensionPixelSize(R.dimen.details_screenshot_margin); | ||||
|                 displayImageOptions = new DisplayImageOptions.Builder() | ||||
|                         .cacheInMemory(true) | ||||
|                         .cacheOnDisk(true) | ||||
|                         .imageScaleType(ImageScaleType.NONE) | ||||
|                         .showImageOnLoading(R.drawable.ic_repo_app_default) | ||||
|                         .showImageForEmptyUri(R.drawable.ic_repo_app_default) | ||||
|                         .bitmapConfig(Bitmap.Config.RGB_565) | ||||
|                         .build(); | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { | ||||
|                 ScreenShotViewHolder vh = (ScreenShotViewHolder) holder; | ||||
|                 setViewSelected(vh.itemView, position == selectedPosition); | ||||
|                 if (position == selectedPosition) | ||||
|                     this.selectedView = vh.itemView; | ||||
|                 ImageLoader.getInstance().displayImage(mApp.iconUrlLarge, vh.image, displayImageOptions); | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { | ||||
|                 View view = LayoutInflater.from(parent.getContext()) | ||||
|                         .inflate(R.layout.app_details2_screenshot_item, parent, false); | ||||
|                 return new ScreenShotViewHolder(view); | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public int getItemCount() { | ||||
|                 return 7; | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public void onSnappedToView(View view, int snappedPosition) { | ||||
|                 setViewSelected(selectedView, false); | ||||
|                 selectedView = view; | ||||
|                 selectedPosition = snappedPosition; | ||||
|                 setViewSelected(selectedView, true); | ||||
|             } | ||||
| 
 | ||||
|             private void setViewSelected(View view, boolean selected) { | ||||
|                 if (view != null) { | ||||
|                     RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams)view.getLayoutParams(); | ||||
|                     if (selected) | ||||
|                         lp.setMargins(0,selectedItemElevation,0,selectedItemElevation); | ||||
|                     else | ||||
|                         lp.setMargins(0,unselectedItemMargin,0,unselectedItemMargin); | ||||
|                     ViewCompat.setElevation(view, selected ? selectedItemElevation : 0); | ||||
|                     view.setLayoutParams(lp); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             public class ScreenShotViewHolder extends RecyclerView.ViewHolder { | ||||
|                 final ImageView image; | ||||
| 
 | ||||
|                 ScreenShotViewHolder(View view) { | ||||
|                     super(view); | ||||
|                     image = (ImageView) view.findViewById(R.id.image); | ||||
|                 } | ||||
| 
 | ||||
|                 @Override | ||||
|                 public String toString() { | ||||
|                     return super.toString() + " screenshot"; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // The HTML formatter adds "\n\n" at the end of every paragraph. This | ||||
|     // is desired between paragraphs, but not at the end of the whole | ||||
|     // string as it adds unwanted spacing at the end of the TextView. | ||||
|     // Remove all trailing newlines. | ||||
|     // Use this function instead of a trim() as that would require | ||||
|     // converting to String and thus losing formatting (e.g. bold). | ||||
|     private static CharSequence trimNewlines(CharSequence s) { | ||||
|         if (s == null || s.length() < 1) { | ||||
|             return s; | ||||
|         } | ||||
|         int i; | ||||
|         for (i = s.length() - 1; i >= 0; i--) { | ||||
|             if (s.charAt(i) != '\n') { | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         if (i == s.length() - 1) { | ||||
|             return s; | ||||
|         } | ||||
|         return s.subSequence(0, i + 1); | ||||
|     } | ||||
| 
 | ||||
|     private static final class SafeLinkMovementMethod extends LinkMovementMethod { | ||||
| 
 | ||||
|         private static AppDetails2.SafeLinkMovementMethod instance; | ||||
| 
 | ||||
|         private final Context ctx; | ||||
| 
 | ||||
|         private SafeLinkMovementMethod(Context ctx) { | ||||
|             this.ctx = ctx; | ||||
|         } | ||||
| 
 | ||||
|         public static AppDetails2.SafeLinkMovementMethod getInstance(Context ctx) { | ||||
|             if (instance == null) { | ||||
|                 instance = new AppDetails2.SafeLinkMovementMethod(ctx); | ||||
|             } | ||||
|             return instance; | ||||
|         } | ||||
| 
 | ||||
|         private static CharSequence getLink(TextView widget, Spannable buffer, | ||||
|                                             MotionEvent event) { | ||||
|             int x = (int) event.getX(); | ||||
|             int y = (int) event.getY(); | ||||
|             x -= widget.getTotalPaddingLeft(); | ||||
|             y -= widget.getTotalPaddingTop(); | ||||
|             x += widget.getScrollX(); | ||||
|             y += widget.getScrollY(); | ||||
| 
 | ||||
|             Layout layout = widget.getLayout(); | ||||
|             final int line = layout.getLineForVertical(y); | ||||
|             final int off = layout.getOffsetForHorizontal(line, x); | ||||
|             final ClickableSpan[] links = buffer.getSpans(off, off, ClickableSpan.class); | ||||
| 
 | ||||
|             if (links.length > 0) { | ||||
|                 final ClickableSpan link = links[0]; | ||||
|                 final Spanned s = (Spanned) widget.getText(); | ||||
|                 return s.subSequence(s.getSpanStart(link), s.getSpanEnd(link)); | ||||
|             } | ||||
|             return "null"; | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public boolean onTouchEvent(@NonNull TextView widget, @NonNull Spannable buffer, | ||||
|                                     @NonNull MotionEvent event) { | ||||
|             try { | ||||
|                 return super.onTouchEvent(widget, buffer, event); | ||||
|             } catch (ActivityNotFoundException ex) { | ||||
|                 Selection.removeSelection(buffer); | ||||
|                 final CharSequence link = getLink(widget, buffer, event); | ||||
|                 Toast.makeText(ctx, | ||||
|                         ctx.getString(R.string.no_handler_app, link), | ||||
|                         Toast.LENGTH_LONG).show(); | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| @ -20,6 +20,7 @@ package org.fdroid.fdroid; | ||||
| 
 | ||||
| import android.content.Context; | ||||
| import android.content.pm.PackageManager; | ||||
| import android.content.res.Resources; | ||||
| import android.database.Cursor; | ||||
| import android.graphics.Bitmap; | ||||
| import android.net.Uri; | ||||
| @ -31,6 +32,7 @@ import android.text.Html; | ||||
| import android.text.TextUtils; | ||||
| import android.util.DisplayMetrics; | ||||
| import android.util.Log; | ||||
| import android.util.TypedValue; | ||||
| 
 | ||||
| import com.nostra13.universalimageloader.core.DisplayImageOptions; | ||||
| import com.nostra13.universalimageloader.core.assist.ImageScaleType; | ||||
| @ -596,4 +598,9 @@ public final class Utils { | ||||
|         return data; | ||||
|     } | ||||
| 
 | ||||
|     public static int dpToPx(int dp, Context ctx) | ||||
|     { | ||||
|         Resources r = ctx.getResources(); | ||||
|         return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,74 @@ | ||||
| package org.fdroid.fdroid.views; | ||||
| 
 | ||||
| import android.support.v4.view.ViewCompat; | ||||
| import android.support.v7.widget.LinearLayoutManager; | ||||
| import android.support.v7.widget.LinearSnapHelper; | ||||
| import android.support.v7.widget.OrientationHelper; | ||||
| import android.support.v7.widget.RecyclerView; | ||||
| import android.view.View; | ||||
| 
 | ||||
| import static android.support.v7.widget.RecyclerView.NO_POSITION; | ||||
| 
 | ||||
| public class LinearLayoutManagerSnapHelper extends LinearSnapHelper { | ||||
| 
 | ||||
|     public interface LinearSnapHelperListener { | ||||
|         /** | ||||
|          * Tells the listener that we have selected a view to snap to. | ||||
|          * @param view The selected view (may be null) | ||||
|          * @param position Adapter position of the snapped to view (or NO_POSITION if none) | ||||
|          */ | ||||
|         void onSnappedToView(View view, int position); | ||||
|     }; | ||||
| 
 | ||||
|     private LinearLayoutManager mLlm; | ||||
|     private OrientationHelper mOrientationHelper; | ||||
|     private LinearSnapHelperListener mListener; | ||||
| 
 | ||||
|     public LinearLayoutManagerSnapHelper(LinearLayoutManager llm) { | ||||
|         this.mLlm = llm; | ||||
|         this.mOrientationHelper = OrientationHelper.createHorizontalHelper(mLlm); | ||||
|     }; | ||||
| 
 | ||||
|     public void setLinearSnapHelperListener(LinearSnapHelperListener listener) { | ||||
|         mListener = listener; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public View findSnapView(RecyclerView.LayoutManager layoutManager) { | ||||
|         View snappedView = super.findSnapView(layoutManager); | ||||
|         if (layoutManager.canScrollHorizontally()) { | ||||
|             if (layoutManager instanceof LinearLayoutManager) { | ||||
|                 int firstChild = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition(); | ||||
|                 int lastChild = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition(); | ||||
|                 if (firstChild == 0) { | ||||
|                     View child = layoutManager.findViewByPosition(firstChild); | ||||
|                     if (mOrientationHelper.getDecoratedEnd(child) >= mOrientationHelper.getDecoratedMeasurement(child) / 2 | ||||
|                             && mOrientationHelper.getDecoratedEnd(child) > 0) { | ||||
|                         int dist1 = super.calculateDistanceToFinalSnap(layoutManager, snappedView)[0]; | ||||
|                         int dist2 = mOrientationHelper.getDecoratedStart(child); | ||||
|                         if (Math.abs(dist1) > Math.abs(dist2)) { | ||||
|                             snappedView = child; | ||||
|                         } | ||||
|                     } | ||||
|                 } else if (lastChild == (mLlm.getItemCount() - 1)) { | ||||
|                     View child = layoutManager.findViewByPosition(lastChild); | ||||
|                     if (mOrientationHelper.getDecoratedStart(child) < mOrientationHelper.getTotalSpace() - mOrientationHelper.getDecoratedMeasurement(child) / 2 | ||||
|                             && mOrientationHelper.getDecoratedStart(child) < mOrientationHelper.getTotalSpace()) { | ||||
|                         int dist1 = super.calculateDistanceToFinalSnap(layoutManager, snappedView)[0]; | ||||
|                         int dist2 = mOrientationHelper.getTotalSpace() - mOrientationHelper.getDecoratedEnd(child); | ||||
|                         if (Math.abs(dist1) > Math.abs(dist2)) { | ||||
|                             snappedView = child; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         if (mListener != null) { | ||||
|             int snappedPosition = 0; | ||||
|             if (snappedView != null) | ||||
|                 snappedPosition = mLlm.getPosition(snappedView); | ||||
|             mListener.onSnappedToView(snappedView, snappedPosition); | ||||
|         } | ||||
|         return snappedView; | ||||
|     } | ||||
| } | ||||
| @ -20,6 +20,7 @@ import android.widget.AdapterView; | ||||
| import android.widget.TextView; | ||||
| 
 | ||||
| import org.fdroid.fdroid.AppDetails; | ||||
| import org.fdroid.fdroid.AppDetails2; | ||||
| import org.fdroid.fdroid.Preferences; | ||||
| import org.fdroid.fdroid.R; | ||||
| import org.fdroid.fdroid.UpdateService; | ||||
| @ -30,6 +31,7 @@ import org.fdroid.fdroid.views.AppListAdapter; | ||||
| 
 | ||||
| public abstract class AppListFragment extends ListFragment implements | ||||
|         AdapterView.OnItemClickListener, | ||||
|         AdapterView.OnItemLongClickListener, | ||||
|         Preferences.ChangeListener, | ||||
|         LoaderManager.LoaderCallbacks<Cursor> { | ||||
| 
 | ||||
| @ -109,6 +111,7 @@ public abstract class AppListFragment extends ListFragment implements | ||||
|         // returns the list view is "called between onCreate and | ||||
|         // onActivityCreated" according to the docs. | ||||
|         getListView().setOnItemClickListener(this); | ||||
|         getListView().setOnItemLongClickListener(this); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
| @ -155,11 +158,21 @@ public abstract class AppListFragment extends ListFragment implements | ||||
| 
 | ||||
|     @Override | ||||
|     public void onItemClick(AdapterView<?> parent, View view, int position, long id) { | ||||
|         showItemDetails(view, position, false); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { | ||||
|         showItemDetails(view, position, true); | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     private void showItemDetails(View view, int position, boolean useNewDetailsActivity) { | ||||
|         // Cursor is null in the swap list when touching the first item. | ||||
|         Cursor cursor = (Cursor) getListView().getItemAtPosition(position); | ||||
|         if (cursor != null) { | ||||
|             final App app = new App(cursor); | ||||
|             Intent intent = getAppDetailsIntent(); | ||||
|             Intent intent = getAppDetailsIntent(useNewDetailsActivity); | ||||
|             intent.putExtra(AppDetails.EXTRA_APPID, app.packageName); | ||||
|             intent.putExtra(AppDetails.EXTRA_FROM, getFromTitle()); | ||||
|             if (Build.VERSION.SDK_INT >= 21) { | ||||
| @ -176,8 +189,8 @@ public abstract class AppListFragment extends ListFragment implements | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private Intent getAppDetailsIntent() { | ||||
|         return new Intent(getActivity(), AppDetails.class); | ||||
|     private Intent getAppDetailsIntent(boolean useNewDetailsActivity) { | ||||
|         return new Intent(getActivity(), useNewDetailsActivity ? AppDetails2.class : AppDetails.class); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|  | ||||
							
								
								
									
										
											BIN
										
									
								
								app/src/main/res/drawable-mdpi/feature_placeholder.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								app/src/main/res/drawable-mdpi/feature_placeholder.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 346 KiB | 
| @ -0,0 +1,27 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <selector xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <item android:state_pressed="true"> | ||||
|         <shape android:shape="rectangle"> | ||||
|             <corners android:radius="3dp" /> | ||||
|             <solid android:color="@color/fdroid_blue_dark" /> | ||||
|         </shape> | ||||
|     </item> | ||||
|     <item android:state_checked="true"> | ||||
|         <shape android:shape="rectangle"> | ||||
|             <corners android:radius="3dp" /> | ||||
|             <solid android:color="@color/fdroid_blue_dark" /> | ||||
|         </shape> | ||||
|     </item> | ||||
|     <item android:state_enabled="false"> | ||||
|         <shape android:shape="rectangle"> | ||||
|             <corners android:radius="3dp" /> | ||||
|             <solid android:color="@color/fdroid_blue_dark" /> | ||||
|         </shape> | ||||
|     </item> | ||||
|     <item> | ||||
|         <shape android:shape="rectangle"> | ||||
|             <corners android:radius="3dp" /> | ||||
|             <solid android:color="@color/fdroid_blue" /> | ||||
|         </shape> | ||||
|     </item> | ||||
| </selector> | ||||
| @ -0,0 +1,28 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <selector xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <item android:state_pressed="true"> | ||||
|         <shape android:shape="rectangle"> | ||||
|             <corners android:radius="3dp" /> | ||||
|             <solid android:color="@color/fdroid_blue" /> | ||||
|         </shape> | ||||
|     </item> | ||||
|     <item android:state_checked="true"> | ||||
|         <shape android:shape="rectangle"> | ||||
|             <corners android:radius="3dp" /> | ||||
|             <solid android:color="@color/fdroid_blue" /> | ||||
|         </shape> | ||||
|     </item> | ||||
|     <item android:state_enabled="false"> | ||||
|         <shape android:shape="rectangle"> | ||||
|             <corners android:radius="3dp" /> | ||||
|             <solid android:color="@color/fdroid_blue" /> | ||||
|         </shape> | ||||
|     </item> | ||||
|     <item> | ||||
|         <shape android:shape="rectangle"> | ||||
|             <corners android:radius="3dp" /> | ||||
|             <solid android:color="@android:color/white" /> | ||||
|             <stroke android:color="@color/fdroid_blue" android:width="2dp" /> | ||||
|         </shape> | ||||
|     </item> | ||||
| </selector> | ||||
							
								
								
									
										46
									
								
								app/src/main/res/layout/activity_app_details2.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								app/src/main/res/layout/activity_app_details2.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:app="http://schemas.android.com/apk/res-auto" | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="match_parent" | ||||
|     android:fitsSystemWindows="true" | ||||
|     tools:context="org.fdroid.fdroid.AppDetails2"> | ||||
| 
 | ||||
|     <android.support.design.widget.AppBarLayout | ||||
|         android:id="@+id/app_bar" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="@dimen/app_bar_height" | ||||
|         android:fitsSystemWindows="true" | ||||
|         android:theme="@style/AppThemeLight.AppBarOverlay"> | ||||
| 
 | ||||
|         <android.support.design.widget.CollapsingToolbarLayout | ||||
|             android:id="@+id/toolbar_layout" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="match_parent" | ||||
|             android:fitsSystemWindows="true" | ||||
|             app:contentScrim="?attr/colorPrimary" | ||||
|             app:layout_scrollFlags="scroll|exitUntilCollapsed"> | ||||
| 
 | ||||
|             <ImageView | ||||
|                 android:id="@+id/backdrop" | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="match_parent" | ||||
|                 android:scaleType="centerCrop" | ||||
|                 android:fitsSystemWindows="true" | ||||
|                 android:src="@drawable/feature_placeholder" | ||||
|                 app:layout_collapseMode="parallax" /> | ||||
| 
 | ||||
|             <android.support.v7.widget.Toolbar | ||||
|                 android:id="@+id/toolbar" | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="?attr/actionBarSize" | ||||
|                 app:layout_collapseMode="pin" | ||||
|                 app:popupTheme="@style/AppThemeLight.PopupOverlay" /> | ||||
| 
 | ||||
|         </android.support.design.widget.CollapsingToolbarLayout> | ||||
|     </android.support.design.widget.AppBarLayout> | ||||
| 
 | ||||
|     <include layout="@layout/content_app_details2" /> | ||||
| 
 | ||||
| </android.support.design.widget.CoordinatorLayout> | ||||
							
								
								
									
										125
									
								
								app/src/main/res/layout/app_details2_header.xml
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										125
									
								
								app/src/main/res/layout/app_details2_header.xml
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,125 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:app="http://schemas.android.com/apk/res-auto" | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="wrap_content" | ||||
|     android:layout_margin="16dp" | ||||
|     app:cardBackgroundColor="#efefef" | ||||
|     app:cardCornerRadius="3dp" | ||||
|     app:cardElevation="3dp"> | ||||
| 
 | ||||
|     <LinearLayout | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:padding="8dp" | ||||
|         android:orientation="vertical"> | ||||
| 
 | ||||
|         <RelativeLayout | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="wrap_content" | ||||
| 
 | ||||
|             > | ||||
| 
 | ||||
|             <ImageView | ||||
|                 android:id="@+id/icon" | ||||
|                 android:layout_width="72dp" | ||||
|                 android:layout_height="72dp" | ||||
|                 android:paddingRight="8dp" | ||||
|                 android:paddingBottom="8dp" | ||||
|                 android:layout_alignParentLeft="true" | ||||
|                 android:layout_alignParentStart="true" | ||||
|                 android:layout_alignParentTop="true" | ||||
|                 android:src="@drawable/ic_repo_app_default" /> | ||||
| 
 | ||||
|             <TextView | ||||
|                 android:id="@+id/title" | ||||
|                 android:layout_width="0dp" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:layout_alignParentEnd="true" | ||||
|                 android:layout_alignParentRight="true" | ||||
|                 android:layout_alignParentTop="true" | ||||
|                 android:layout_toEndOf="@id/icon" | ||||
|                 android:layout_toRightOf="@id/icon" | ||||
|                 android:textAppearance="@style/TextAppearance.AppCompat.Headline" | ||||
|                 tools:text="App Title" /> | ||||
| 
 | ||||
|             <TextView | ||||
|                 android:id="@+id/author" | ||||
|                 android:layout_width="0dp" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:layout_alignEnd="@id/title" | ||||
|                 android:layout_alignLeft="@id/title" | ||||
|                 android:layout_alignRight="@id/title" | ||||
|                 android:layout_alignStart="@id/title" | ||||
|                 android:layout_below="@id/title" | ||||
|                 android:textAppearance="@style/TextAppearance.AppCompat.Body1" | ||||
|                 tools:text="Author" /> | ||||
| 
 | ||||
|             <LinearLayout | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:layout_below="@id/icon" | ||||
|                 android:layout_toEndOf="@id/icon" | ||||
|                 android:layout_toRightOf="@id/icon" | ||||
|                 android:layout_alignParentEnd="true" | ||||
|                 android:layout_alignParentRight="true"> | ||||
| 
 | ||||
|                 <Button | ||||
|                     android:id="@+id/secondaryButtonView" | ||||
|                     style="@style/DetailsSecondaryButtonStyle" | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:layout_weight="1" | ||||
|                     android:maxLines="1" | ||||
|                     android:ellipsize="marquee" | ||||
|                     android:text="THIS IS BUTTON 1" /> | ||||
| 
 | ||||
|                 <Button | ||||
|                     android:id="@+id/primaryButtonView" | ||||
|                     style="@style/DetailsPrimaryButtonStyle" | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:layout_marginLeft="8dp" | ||||
|                     android:layout_marginStart="8dp" | ||||
|                     android:layout_weight="1" | ||||
|                     android:maxLines="1" | ||||
|                     android:ellipsize="marquee" | ||||
|                     android:text="THIS IS 2" /> | ||||
|             </LinearLayout> | ||||
| 
 | ||||
|         </RelativeLayout> | ||||
| 
 | ||||
|         <TextView | ||||
|             android:id="@+id/summary" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="wrap_content" | ||||
|             android:layout_marginTop="16dp" | ||||
|             android:textAppearance="@style/TextAppearance.AppCompat.Body1" | ||||
|             tools:text="This app is awezome" | ||||
|             android:scrollbars="none" | ||||
|             android:textStyle="bold" | ||||
|             /> | ||||
| 
 | ||||
|         <TextView | ||||
|             android:id="@+id/description" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="wrap_content" | ||||
|             android:layout_marginTop="16dp" | ||||
|             android:textAppearance="@style/TextAppearance.AppCompat.Body1" | ||||
|             tools:text="This is the app description of this awezome app. It can be several lines long, but will be truncated at just a few if it is. A 'read more' button will appear so that you can expand the view and view the full text, if you wish. Yes, it will be blue and beautiful." | ||||
|             android:scrollbars="none" | ||||
|             /> | ||||
| 
 | ||||
|         <TextView | ||||
|             android:id="@+id/description_more" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="wrap_content" | ||||
|             android:textAppearance="@style/TextAppearance.AppCompat.Body1" | ||||
|             style="@style/DetailsMoreButtonStyle" | ||||
|             android:gravity="right|end" | ||||
|             android:text="@string/more" | ||||
|             tools:text="more" /> | ||||
| 
 | ||||
|     </LinearLayout> | ||||
| </android.support.v7.widget.CardView> | ||||
							
								
								
									
										19
									
								
								app/src/main/res/layout/app_details2_screenshot_item.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								app/src/main/res/layout/app_details2_screenshot_item.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:layout_width="wrap_content" | ||||
|     android:layout_height="match_parent" | ||||
|     xmlns:app="http://schemas.android.com/apk/res-auto" | ||||
|     app:cardElevation="3dp" | ||||
|     app:cardBackgroundColor="#ffffff" | ||||
|     android:padding="10dp" | ||||
|     android:layout_marginTop="16dp" | ||||
|     android:layout_marginBottom="16dp" | ||||
|     > | ||||
|     <ImageView | ||||
|         android:id="@+id/image" | ||||
|         android:layout_width="wrap_content" | ||||
|         android:layout_height="match_parent" | ||||
|         android:adjustViewBounds="true" | ||||
|         android:scaleType="fitCenter" | ||||
|         /> | ||||
| </android.support.v7.widget.CardView> | ||||
							
								
								
									
										7
									
								
								app/src/main/res/layout/app_details2_screenshots.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								app/src/main/res/layout/app_details2_screenshots.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <android.support.v7.widget.RecyclerView | ||||
|     xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:id="@+id/screenshots" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="150dp"> | ||||
| </android.support.v7.widget.RecyclerView> | ||||
							
								
								
									
										8
									
								
								app/src/main/res/layout/app_details2_whatsnew.xml
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										8
									
								
								app/src/main/res/layout/app_details2_whatsnew.xml
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,8 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <TextView xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:id="@+id/text" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="wrap_content" | ||||
|     android:layout_margin="16dp" | ||||
|     android:textAppearance="@style/TextAppearance.AppCompat.Body1" | ||||
| /> | ||||
							
								
								
									
										14
									
								
								app/src/main/res/layout/content_app_details2.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								app/src/main/res/layout/content_app_details2.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <android.support.v7.widget.RecyclerView | ||||
|     xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:app="http://schemas.android.com/apk/res-auto" | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     android:id="@+id/rvDetails" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="match_parent" | ||||
|     app:layout_behavior="@string/appbar_scrolling_view_behavior" | ||||
|     app:behavior_overlapTop="40dp" | ||||
|     app:layoutManager="LinearLayoutManager" | ||||
|     tools:context="org.fdroid.fdroid.AppDetails2" | ||||
|     tools:showIn="@layout/activity_app_details2"> | ||||
| </android.support.v7.widget.RecyclerView> | ||||
| @ -18,4 +18,11 @@ | ||||
|         <item name="android:colorButtonNormal">#04b9e6</item> | ||||
|     </style> | ||||
| 
 | ||||
|     <style name="AppThemeLight.NoActionBar"> | ||||
|         <item name="windowActionBar">false</item> | ||||
|         <item name="windowNoTitle">true</item> | ||||
|         <item name="android:windowDrawsSystemBarBackgrounds">true</item> | ||||
|         <item name="android:statusBarColor">@android:color/transparent</item> | ||||
|     </style> | ||||
| 
 | ||||
| </resources> | ||||
|  | ||||
| @ -3,5 +3,10 @@ | ||||
| 
 | ||||
|     <dimen name="layout_horizontal_margin">16dp</dimen> | ||||
|     <dimen name="material_listitem_height">48dp</dimen> | ||||
|     <dimen name="app_bar_height">180dp</dimen> | ||||
|     <!-- "Not selected" items are inset by this value, while the selected one is not --> | ||||
|     <dimen name="details_screenshot_margin">16dp</dimen> | ||||
|     <!-- The selected item stands out from the background by this elevation --> | ||||
|     <dimen name="details_screenshot_selected_elevation">3dp</dimen> | ||||
| 
 | ||||
| </resources> | ||||
|  | ||||
| @ -246,4 +246,13 @@ | ||||
|     <style name="AppDetailsSubheaderText" parent="AppDetailsSubheaderTextBase" /> | ||||
| 
 | ||||
|     <style name="AppThemeTransparent" parent="@android:style/Theme.NoDisplay" /> | ||||
| 
 | ||||
|     <style name="AppThemeLight.NoActionBar"> | ||||
|         <item name="windowActionBar">false</item> | ||||
|         <item name="windowNoTitle">true</item> | ||||
|     </style> | ||||
| 
 | ||||
|     <style name="AppThemeLight.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" /> | ||||
| 
 | ||||
|     <style name="AppThemeLight.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" /> | ||||
| </resources> | ||||
|  | ||||
							
								
								
									
										26
									
								
								app/src/main/res/values/styles_detail.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								app/src/main/res/values/styles_detail.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <resources> | ||||
|     <style name="DetailsPrimaryButtonStyle"> | ||||
|         <item name="android:padding">5dp</item> | ||||
|         <item name="android:textSize">12sp</item> | ||||
|         <item name="android:textStyle">normal</item> | ||||
|         <item name="android:textColor">#ffffff</item> | ||||
|         <item name="android:background">@drawable/button_primary_background_selector</item> | ||||
|     </style> | ||||
| 
 | ||||
|     <style name="DetailsSecondaryButtonStyle"> | ||||
|         <item name="android:padding">5dp</item> | ||||
|         <item name="android:textSize">12sp</item> | ||||
|         <item name="android:textStyle">normal</item> | ||||
|         <item name="android:textColor">@color/fdroid_blue</item> | ||||
|         <item name="android:background">@drawable/button_secondary_background_selector</item> | ||||
|     </style> | ||||
| 
 | ||||
|     <style name="DetailsMoreButtonStyle"> | ||||
|         <item name="android:padding">5dp</item> | ||||
|         <item name="android:textSize">15sp</item> | ||||
|         <item name="android:textStyle">normal</item> | ||||
|         <item name="android:textColor">@color/fdroid_blue</item> | ||||
|     </style> | ||||
| 
 | ||||
| </resources> | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 mvp76
						mvp76