⬆️ ⬇️

Creating a horizontal scroll with gradient and arrows

I'll tell you how to create a horizontal block that scrolls right / left. Which arrows disappear around the edges (when we have reached the end). And which has a gradient fill.



image





')

Small introduction





Not so long ago, I had to start programming again with Java in PHP for Android (before that, 5 years ago I had hardly worked on Java, it happened). At work, it was necessary to create an application. Naturally, to create some elements I had to go to http://stackoverflow.com/ and some other sites (including official documentation), but strangely enough, there is no description of the necessary elements and you have to write them from scratch (or use parts from other functionals).



What do I need to do





In the design there was an element of such a simple, seemingly, kind:

image



Start of search





At first I decided that this item would be very easy to create. But faced with a number of problems.

1. Gradient

2. Converting colors from #rrggbb

3. Download images from the Internet for background

4. Left and right buttons

5. Creating text fields in horizontal scrolling dynamically



Let's start with the gradient as the easiest




I found a huge amount of material how to make a gradient in XML, but my task was to change the gradient from one section to another. a piece of code was found here :



int colors[] = { 0xff255779 , 0xff3e7492, 0xffa6c0cd }; GradientDrawable g = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, colors); setBackgroundDrawable(g); 




This code creates a gradient and fills it as a background. This is what I needed. But here I was faced with the fact that sometimes I need not only a gradient, but also an insert of a picture on the background, and the picture needs to be filled in completely.



But more on that below.

First you need to convert the color from #rrggbb to 0xffa6c0cd.



Color conversion from #rrggbb




For this function was written:



  public int getBackgoundColorAsInt(String bgcolor){ try{ int result = new BigInteger(bgcolor.replace("#", "FF"),16).intValue(); return result; }catch(Exception e){ Log.e("Error in switch color from String to int","Can't switch bg color : " + bgcolor); return new BigInteger("FFCCCCCC",16).intValue(); } } 




The function converts the string to an int and returns the resulting number to us.

With color figured out. Now let's deal with the picture.



Download images from the internet for background




After a long search, the function that found me the most was found here :

  public Drawable LoadImageFromWebOperations(String url) { try { InputStream is = (InputStream) new URL(url).getContent(); Drawable d = Drawable.createFromStream(is, "src name"); return d; } catch (Exception e) { Log.e("Error in load image", "Can't load image from url " + url); return null; } } 




Everything is easy and understandable.



Left and right buttons


It's time to create an XML file for the side parts (to the right and to the left of the scroll itself)

Here I will give only a piece of code that I got at the very end. After heaps of experiments.



  <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_vertical" android:background="#0000ff" android:id="@+id/top_menu_categories_layout" android:layout_weight="1" android:visibility="gone" > <ImageView android:id="@+id/subcategory_left_scroll_img" android:background="@drawable/top_menu_prev_category" android:layout_height="wrap_content" android:layout_width="25dp" android:visibility="invisible" android:layout_weight=".15" /> <com.lid.app.custom_views.SubcategoryScrollView android:id="@+id/HorizontalScrollView01" android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight=".70" > <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="fill_parent" android:gravity="center_vertical" android:background="#0000ff" > </RelativeLayout> </com.lid.app.custom_views.SubcategoryScrollView> <ImageView android:id="@+id/subcategory_right_scroll_img" android:background="@drawable/top_menu_next_category" android:layout_height="wrap_content" android:layout_width="25dp" android:layout_weight=".15" /> </LinearLayout> 




And now I will answer the question that immediately arose - and why is my own element used here?



  public class SubcategoryScrollView extends HorizontalScrollView { //   private ImageView left_scroll; //   private ImageView left_scroll; //   private int display_width; public SubcategoryScrollView(Context context) { super(context); } public SubcategoryScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public SubcategoryScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public void onScrollChanged(int l, int t, int oldl, int oldt) { if(l > 0){ if(this.left_scroll.getVisibility() != View.VISIBLE){ this.left_scroll.setVisibility(View.VISIBLE); } }else{ this.left_scroll.setVisibility(View.INVISIBLE); } if (this.getWidth() + l >= this.computeHorizontalScrollRange()) { this.left_scroll.setVisibility(View.INVISIBLE); }else{ this.left_scroll.setVisibility(View.VISIBLE); } super.onScrollChanged(l, t, oldl, oldt); } @Override protected void onDraw (Canvas canvas){ super.onDraw(canvas); if(this.getScrollX() == 0){ if(this.computeHorizontalScrollRange() <= this.display_width){ this.left_scroll.setVisibility(View.INVISIBLE); }else{ this.left_scroll.setVisibility(View.VISIBLE); } } } /** * @param left_scroll the left_scroll to set * @author gron */ public void setleft_scroll(ImageView left_scroll) { this.left_scroll = left_scroll; } /** * @return the left_scroll * @author gron */ public ImageView getleft_scroll() { return left_scroll; } /** * @param left_scroll the left_scroll to set * @author gron */ public void setleft_scroll(ImageView left_scroll) { this.left_scroll = left_scroll; } /** * @return the left_scroll * @author gron */ public ImageView getleft_scroll() { return left_scroll; } /** * @param display_width the display_width to set */ public void setDisplayWidth(int display_width) { this.display_width = display_width; } /** * @return the display_width */ public int getDisplayWidth() { return display_width; } } 


That's why I needed this element. When drawing and scrolling, I want the button drawings to be hidden.

When drawing, the width of the screen is checked (consider below) and if the width of all elements inside the scroll is less than the width of the screen, then the right button is not displayed.

When scrolling, too, buttons can be hidden.



Note that OnDraw () is called after onScrollChanged ()

Maybe he did not read attentively, but he did not find it and suffered for a very long time why scrolling does not work the way I want.



Now we know how to create a gradient, transform colors, create a drawable from an Internet drawing, hide buttons when scrolling and drawing. It remains only to combine all the knowledge in one and make sure that the buttons are added dynamically



And everything was very, very simple, if, as always, there were no pitfalls.



Creating text fields in horizontal scrolling dynamically



I will give the code in chunks, sorry, copying from the finished project.



To begin with, we will do a small conversion in order to use the gradient normally.

  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:layout_width="fill_parent" android:id="@+id/main_layout" > <ImageView android:id="@+id/subcategory_background_img" android:layout_width="fill_parent" android:layout_height="41dp" android:scaleType="fitXY" android:visibility="invisible" android:layout_below="@id/top_menu_layout" /> <include layout="@layout/top_menu_subcategories_layout" <----------       2-  android:id="@+id/top_menu_categories_layout" android:layout_width="fill_parent" android:layout_height="41dp" android:layout_below="@id/top_menu_layout" /> </RelativeLayout> 




Now we will write our code:

  final LinearLayout ll = (LinearLayout) this.findViewById(R.id.top_menu_categories_layout); final ImageView background_iv = (ImageView) this.findViewById(R.id.subcategory_background_img); //        LinearLeyout if (remote_url != null) { background_iv.setBackgroundDrawable( //      this.LoadImageFromWebOperations(remote_url) ); background_iv.setVisibility(View.VISIBLE); ll.setBackgroundColor(0); } else { background_iv.setVisibility(View.INVISIBLE); // change color in categories menu int[] colors = new int[2]; colors[0] = current_category.getColors().getBackgoundColorAsInt( color1 ); colors[1] = current_category.getColors().getBackgoundColorAsInt( color2 ); final GradientDrawable gd = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, colors); ll.setBackgroundDrawable(gd); } final SubcategoryScrollView hs_view = (SubcategoryScrollView) this.findViewById(R.id.HorizontalScrollView01); final ImageView iv = (ImageView) this.findViewById(R.id.top_menu_select_category); final ImageView scroll_left_iv = (ImageView) this.findViewById(R.id.subcategory_left_scroll_img); final ImageView scroll_right_iv = (ImageView) this.findViewById(R.id.subcategory_right_scroll_img); //  HorizontalScroll     . RelativeLayout layout = new RelativeLayout(this); TextView tv_old = new TextView(getApplicationContext()); //     if (subcategories != null) { //    hs_view.setDisplayWidth(getWindowManager().getDefaultDisplay().getWidth()); hs_view.scrollTo(0, 0); hs_view.setHorizontalScrollBarEnabled(false); hs_view.removeAllViews(); hs_view.setleft_scroll(scroll_left_iv); hs_view.setleft_scroll(scroll_right_iv); int i = 1; //    ,         dpi final float left_margin = 5.0f; final float top_margin = 2.0f; final float padding = 8.0f; final float scale = getResources().getDisplayMetrics().density; int m_left = (int) (left_margin * scale + 0.5f); int t_left = (int) (top_margin * scale + 0.5f); int pad = (int) (padding * scale + 0.5f); // Subcategory          . for (Subcategory item : subcategories) { TextView tv = new TextView(this); RelativeLayout.LayoutParams lparams = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT ); tv.setText(item.getTitle()); tv.setTextColor(Color.WHITE); //        if (i > 1) { lparams.setMargins(m_left, t_left, 0, 0); } else { lparams.setMargins(0, t_left, 0, 0); } //             if (i > 1) { lparams.addRule(RelativeLayout.RIGHT_OF, tv_old.getId()); } tv.setPadding(pad, pad, pad, pad); tv.setId(i); tv.setLayoutParams(lparams); tv_old = tv; layout.addView(tv, lparams); i++; } //       hs_view.addView(layout); ll.setVisibility(View.VISIBLE); } 




Everything. We have ready horizontal scrolling.



Any comments are welcome, the program is still in development.



Upd 1. Image gradient from the Internet

image



Upd 2. Corrected the code, thanks to pyjamec for writing about it.

Source: https://habr.com/ru/post/127005/



All Articles