SoFunction
Updated on 2025-04-06

Android custom control case summary 1 (menu, popupwindow, viewpager)

Custom controls are written by yourself according to your own needs. The controls that come with Android cannot meet your needs. In this case, we can only implement controls that are suitable for the project by ourselves. At the same time, Android also allows you to inherit existing controls or implement your own controls in order to optimize the interface and create a richer user experience. In ordinary projects, we artificially divide custom controls into two types: one is the combination implementation. One is achieved by inheriting view or viewgroup and its subclasses. Both can achieve the results we want, so we can choose the right solution according to our needs. This article shows several more common custom controls in the form of a case.

Case 1Youku menu:

Function introduction: There is a semicircle at the bottom center of the mobile phone interface. The initial status displays a three-level menu, from the outside to the inside, is the third-level menu, the second-level menu, and the third-level menu. There are some buttons in each menu, which can be represented by 3 containers (RelativeLayout) and add buttons to it. When clicking on the picture in the center position again, hide the items on the two layers outside. When you click the picture at the center of gravity again, rotate the secondary menu. When you click on the center position of the second level menu, rotate the third level menu, and click again to hide the third level menu. The above is the function that Youku menu needs to implement.

Implementation steps:

1. Complete the layout file. Because there are many controls, the layout of Youku menu is more complicated, but three sub-linear layouts can be set in a root layout to wrap each small control. Adjusting margin value makes the interface more beautiful. Pay attention to the order of the layout of the three menus, first put menu3, then menu2, and then menu1. The order cannot be reversed, because the menu placed backwards is more above the interface, so that the menu 1 with the smallest area will be at the top, and menu 1 will not obstruct menu 2 and menu 3 below.

2. After completing the layout file, create a class to implement business logic in the class. First, you need to create the state of two Boolean types of constant storage menus. Use the swich statement to determine whether the clicked control is a secondary menu or a primary menu. If the center of the first-level menu is clicked, it is determined whether the third-level menu is open. If the third-level menu is open, hide the first-level menu and the second-level menu and modify the status. If the third-level menu is hidden, determine whether the second-level menu is hidden. If the secondary menu is open, the secondary menu is hidden. If the secondary menu is hidden, the secondary menu will be opened. If the center of the secondary menu is clicked, you only need to determine whether the third-level menu is hidden. If the Level 3 menu is open, the Level 3 menu is hidden. If the third-level menu is hidden, the third-level menu will be opened. At the same time, the menu status must be modified.

3. Next, you can implement the animation effect in a tool class. Both hiding and display in step 2 are achieved through animation effects. The animation effect here uses tween animation, which passes in the starting angle, ending angle, reference object and reference point coordinates for the RotateAnimation object. A small detail is to set the setFillAfter property to true, indicating that the animation starts from the end position, and avoid returning to the starting position after the animation ends. The difference between hidden and display is the starting angle and end angle of rotation. The starting angle set by the display here is -180 and the end angle is 0. The starting angle set by Hide is 0 and the end angle is -180. Of course, it can also be set to other values, depending on the effect you want.

4. Code optimization. When you quickly click the button, you will find that the menu starts to display before it has been hidden, or it is hidden before it has been displayed. Solution: The number of times the monitor animation is turned on is used to determine whether the drawing needs to be executed, and add a listener to the animation class. Set a member variable. When starting the animation is to perform an additional one operation, ending the animation is to perform a subtraction one operation. This way, only when the constant is zero will there be no animation. Therefore, add the judgment in the swich statement if there is currently an animation, wait for the animation to be executed and enter the following logic.

Menu selection interface layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:andro
  android:layout_width="match_parent"
  android:layout_height="match_parent">

  <RelativeLayout
    android:
    android:layout_width="280dp"
    android:layout_height="140dp"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:background="@drawable/level3">

    <ImageButton
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentBottom="true"
      android:layout_marginBottom="6dp"
      android:layout_marginLeft="12dp"
      android:background="@drawable/channel1" />

    <ImageButton
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentBottom="true"
      android:layout_marginBottom="46dp"
      android:layout_marginLeft="32dp"
      android:background="@drawable/channel2" />

    <ImageButton
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentBottom="true"
      android:layout_marginBottom="80dp"
      android:layout_marginLeft="60dp"
      android:background="@drawable/channel3" />

    <ImageButton
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_centerHorizontal="true"
      android:layout_marginTop="6dp"
      android:background="@drawable/channel4" />

    <ImageButton
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentBottom="true"
      android:layout_alignParentRight="true"
      android:layout_marginBottom="80dp"
      android:layout_marginRight="60dp"
      android:background="@drawable/channel5" />

    <ImageButton
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentBottom="true"
      android:layout_alignParentRight="true"
      android:layout_marginBottom="46dp"
      android:layout_marginRight="32dp"
      android:background="@drawable/channel6" />

    <ImageButton
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentBottom="true"
      android:layout_alignParentRight="true"
      android:layout_marginBottom="6dp"
      android:layout_marginRight="12dp"
      android:background="@drawable/channel7" />

  </RelativeLayout>

  <RelativeLayout
    android:
    android:layout_width="180dp"
    android:layout_height="90dp"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:background="@drawable/level2">

    <ImageButton
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentBottom="true"
      android:layout_marginBottom="6dp"
      android:layout_marginLeft="12dp"
      android:background="@drawable/icon_search" />

    <ImageButton
      android:
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_centerHorizontal="true"
      android:layout_marginTop="4dp"
      android:background="@drawable/icon_menu" />

    <ImageButton
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentBottom="true"
      android:layout_alignParentRight="true"
      android:layout_marginBottom="6dp"
      android:layout_marginRight="12dp"
      android:background="@drawable/icon_myyouku" />

  </RelativeLayout>

  <RelativeLayout
    android:
    android:layout_width="100dp"
    android:layout_height="50dp"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:background="@drawable/level1">

    <ImageButton
      android:
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_centerInParent="true"
      android:background="@drawable/icon_home" />

  </RelativeLayout>
</RelativeLayout>


The layout of the main interface, use the pump to press the menu layout to the main interface in the code.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:andro
  xmlns:tools="/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:gravity="center"
  tools:context="">

  <
    android:layout_centerInParent="true"
    android:
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

</RelativeLayout>


The main program is an empty implementation.

import ;
import .;

public class Selectbar extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    (savedInstanceState);
    setContentView(.activity_selectbar);
  }
}


Implementation of main logic.

import ;
import ;
import ;
import ;
import ;

import ;

/**
 * Created by huang on 2016/11/22.
 */
public class Rotate extends RelativeLayout implements  {
  private static final String TAG = "Rotate";
  private RelativeLayout rl_menu1, rl_menu2, rl_menu3;
  private boolean menu2showing = true;
  private boolean menu3showing = true;

  public Rotate(Context context) {
    super(context,null);
  }

  public Rotate(Context context, AttributeSet attrs) {
    super(context, attrs);
    initdata(context);
  }


  private void initdata(Context context) {
    (TAG, "initdata: text");
    View view = (context,.activity_rolate,null);
    (.btn_menu1).setOnClickListener(this);
    (.btn_menu2).setOnClickListener(this);
    rl_menu1 = (RelativeLayout) (.rl_menu1);
    rl_menu2 = (RelativeLayout) (.rl_menu2);
    rl_menu3 = (RelativeLayout) (.rl_menu3);
    addView(view);
  }
  @Override
  public void onClick(View v) {
    switch (()) {
      case .btn_menu2:
        if (()) {
          return;
        }
        if (menu3showing) {
          (rl_menu3);
        } else {
          (rl_menu3);
        }
        menu3showing = !menu3showing;
        break;

      case .btn_menu1:
        if (()) {
          return;
        }
        if (menu3showing) {
          (rl_menu3);
          menu3showing = false;
          (rl_menu2, 300);

        } else if (menu2showing) {
          (rl_menu2);
        } else {
          (rl_menu2);
        }
        menu2showing = !menu2showing;
        break;
    }
  }
}


A tool class is also needed to implement the animation effect.

import ;
import ;
import ;
import ;

/**
 * Created by huang on 2016/11/22.
 */
public class utils {
  private static final String TAG = "utils";
  private static void setviewclickable(View view, boolean clickable) {
    (clickable);
    if (view instanceof ViewGroup) {
      ViewGroup viewgroup = (ViewGroup) view;
      for (int i = 0; i < (); i++) {
        View child = ((ViewGroup) view).getChildAt(i);
        (clickable);
      }
    }
  }

  public static void hiden(View view) {
    float fromDegreeas = 0;
    float toDegrees = -180f;
    rotateview(view, fromDegreeas, toDegrees, 0l);
    setviewclickable(view, false);
  }

  public static void hiden(View view, long startoffset) {
    float fromDegreeas = 0;
    float toDegrees = -180f;
    rotateview(view, fromDegreeas, toDegrees, startoffset);
    setviewclickable(view, false);
  }

  public static void show(View view) {
    float fromDegrees = -180f;
    float toDegrees = 0;
    rotateview(view, fromDegrees, toDegrees, 0l);
    setviewclickable(view, true);
  }

  public static boolean hasAnimationexcuting() {
    return startcount > 0;
  }

  public static void rotateview(View view, float fromDegrees, float toDegrees, long startoffset) {
    int pivotXType = RotateAnimation.RELATIVE_TO_SELF;
    int pivotYType = RotateAnimation.RELATIVE_TO_SELF;
    float pivotXValue = 0.5f;
    float pivatYValue = 1.0f;
    RotateAnimation ra = new RotateAnimation(fromDegrees, toDegrees, pivotXType, pivotXValue, pivotYType, pivatYValue);
    (500);
    (true);
    (startoffset);
    (listener);
    (ra);
  }

  public static int startcount;
  static  listener = new () {
    @Override
    public void onAnimationStart(Animation animation) {
      startcount++;
//      (TAG, "onAnimationStart: " +startcount);
    }

    @Override
    public void onAnimationEnd(Animation animation) {
      startcount--;
//      (TAG, "onAnimationEnd: " + startcount);
    }

    @Override
    public void onAnimationRepeat(Animation animation) {

    }
  };
}


Case 2Popupwindow implementation drop-down list:

Function introduction: Create a textview. When we click on the textview, a list will pop up. The list contains digital information and a deleted picture. List is implemented using listview. Click Delete Picture to delete this record from the list. There are two types of cases in this case. One is to achieve popup effect through the scaling of the animation, and the other is to adopt popupwindow. This article adopts the second solution.

Implementation steps:

Add layout file. First, place a textview on the interface and place a drop-down image on the right side of the textview. In order to place controls more conveniently, relative layout can be adopted, so that as long as the imageview and textview are aligned up, lower and right, the effect can be achieved. In order to make the interface more beautiful, the picture can be set as transparent, that is, the background is null. Here, the popupwindow interface pops up is represented by listview. Therefore, you need to write a separate listview and the layout of each entry, and then use a pump to hit the bottom of the textview.
Writing of Pupupwindow. There are two key steps in writing Popupwindow. One is to new and pupupwimdow objects, passing in related parameters such as the layout to be displayed, the height and width of the layout, whether it is clustered or not. Here, the display interface of pupupwindow is used to load the listview in using a pump. At the same time, the layout of listview items also uses inflate. Therefore, two pumps were used. At the same time, set the listening event for entry clicks for each listview entry, so that the content of the entry can be displayed in the textview when the entry is clicked. . Another key step in writing Popupwindow is showAsDropDown, which is to be displayed below which control it is about to be displayed and how much offset is transmitted. It should be noted that there is a certain error between the actual width and height of the control and the width and height seen, just because the background of the control uses a certain width. Another point is that PopupWindow cannot be hidden when pressing the return key. Setting a background for PopupWindow can solve this problem, as follows: (new ColorDrawable()). Every time PopupWindow is displayed, a new PopupWindow object is created. In fact, a PopupWindow object can be reused. That is, determine whether popupwindow is empty before each creation.
The writing of Listiview entries is relatively fixed. Two optimizations have been made here. One is to take the conferenceview and determine whether the conferenceview is empty before starting the operation. If a new view is created for empty, otherwise the recycled conferenceview will be reused. Another optimization is that every time finviewbyid consumes a lot of memory. Therefore, a class can be defined separately, stored controls, and created once when cnterview is empty. Each time you call, you only need to call the controls in the definition class. Another point is that if the delete icon on the entry is useful, you must set a click event for the deleted image. A small detail is that when buttons and their subclasses exist in listvie entries, they will preempt the focus. Therefore, the imageview is used to delete the image tag here. Of course, you can also take other methods, such as adding this property to the root layout of the entry: android:descendantFocusability="blocksDescendants".

Layout of the main interface:

&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;RelativeLayout xmlns:andro
  xmlns:tools="/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:layout_margin="17dp"
  android:paddingBottom="@dimen/activity_vertical_margin"
  android:paddingLeft="@dimen/activity_horizontal_margin"
  android:paddingRight="@dimen/activity_horizontal_margin"
  android:paddingTop="@dimen/activity_vertical_margin"
  tools:context=""&gt;

  &lt;RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"&gt;

    &lt;EditText
      android:
      android:layout_width="200dp"
      android:layout_height="wrap_content"
      android:hint="Enter an account" /&gt;

    &lt;ImageButton
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignBottom="@id/et_number"
      android:layout_alignRight="@id/et_number"
      android:layout_alignTop="@id/et_number"
      android:background="@null"
      android:onClick="showNumberListToggle"
      android:src="@mipmap/down_arrow" /&gt;
  &lt;/RelativeLayout&gt;
&lt;/RelativeLayout&gt;


Layout of listview entry

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:andro
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:gravity="center_vertical"
  android:orientation="horizontal"
  android:padding="6dp">

  <ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@mipmap/user" />

  <TextView
    android:
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginLeft="6dp"
    android:layout_weight="1"
    android:text="10000"
    android:textSize="18sp" />

  <ImageView
    android:
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@null"
    android:src="@mipmap/delete" />
</LinearLayout>


Write a listview separately.

<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:andro
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:cacheColorHint="@null"
  android:background="@mipmap/listview_background"
  android:descendantFocusability="blocksDescendants">
</ListView> 

Logic in the main program.

import ;
import ;
import .;
import ;
import ;
import ;
import ;
import ;

public class MainActivity extends AppCompatActivity {
  private EditText et_number;
  private PopupWindow popupwindow;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    (savedInstanceState);
    setContentView(.activity_main);
    et_number = (EditText) findViewById(.et_number);
  }

  public void showNumberListToggle(View view) {
    if (popupwindow == null) {          //Reuse popupwindow      View contentView = createContent();
      int width = et_number.getWidth() - 4;
      int height = 400;
      boolean focusable = true;
      popupwindow = new PopupWindow(contentView, width, height, focusable);
      (new ColorDrawable());
    }
    View anchor = et_number;
    int xoff = 2;
    int yoff = -5;
    (anchor, xoff, yoff);
  }

  private View createContent() {
      ListView lv = (ListView) (this, .activity_list, null);
      (new NumberListAdapter());
      (false);
      (monitemclickListener);
    return lv;
  }

   monitemclickListener = new () {
    @Override
    public void onItemClick(AdapterView&lt;?&gt; parent, View view, int position, long id) {
      String number = (String) (position);
      et_number.setText(number);
      ();
    }
  };
}


Adapter writing

import ;
import ;
import ;
import ;
import ;

import ;

/**
 * Created by huang on 2016/11/22.
 */
public class NumberListAdapter extends BaseAdapter {
  private ArrayList<String> numbers = new ArrayList();
  
  {
    for (int i = 0; i < 30; i++) {
      (10000 + i + "" );
    }
  }

  @Override
  public int getCount() {
    return ();
  }

  @Override
  public Object getItem(int position) {
    return (position);
  }

  @Override
  public long getItemId(int position) {
    return position;
  }

  @Override
  public View getView(final int position, View convertView, ViewGroup parent) {
    View view;
    viewHolder holder;
    if(convertView == null){
      view = ((),.item_number_list,null);
      holder = new viewHolder();
      holder.ib_del = (ImageView) (.ib_del);
      holder.tv_number = (TextView) (.tv_numer);
      (holder);
    }else{
      view = convertView;
      holder = (viewHolder)();
    }
    holder.ib_del.setImageResource();
    holder.tv_number.setText((position));
    holder.ib_del.setOnClickListener(new () {
      @Override
      public void onClick(View v) {
        (position);
        notifyDataSetChanged();
      }
    });
    return view;
  }

  static class viewHolder{
     TextView tv_number;
     ImageView ib_del;
  }
}  

Case ThreeViewpager implements carousel diagram:

Function introduction: The implementation of advertising bars, also known as carousel map. Place a ViewPager function at the top of the mobile phone interface to realize the left and right sliding of the interface. There are two types of sliding, one is to automatically slide at a certain time, and it also supports left and right sliding of gestures. A small detail is that small dots placed at the bottom of the carousel image with the number of pictures to indicate which picture is currently selected.
Implementation steps:

1. The layout file consists of two parts, one is the viewpager and the other is the bar and small dot at the bottom. Viewpager exists under the v4 package, so it is compatible with Android 1.6. The bottom bars and small dots are placed in a linear layout, and placed at the bottom of the viewpager, with the text and dots as the center position. Here we will talk about the implementation of small dots. Small dots are made using shape diagrams. Since you can no longer get the number of dots in the layout file, you can place a LinearLayout in the layout file and then add the view object to the LinearLayout in the java code. Also set the status selectors for white and black dots to the background of the view.
2. Next is the writing of viewpager. The key to writing a viewpager is writing an adapter. Write a class inherits PagerAdapter and override the methods in it. Viewpager is to load three pictures by default, one in the middle of the screen, one on the left and right of the screen. We hope that the carousel map can play cyclically, so we can return a sufficiently large value to getcount. When initializing the carousel map, set the initial position of the carousel map in the middle, so that loop playback can be achieved. When we set the getcount return value to a large value, we must also judge the position in the instantiateItem. The passed position is a huge value, but the number of pictures is indeed limited, so you can get the remainder of the position, so that the position position can be corresponding to the number of pictures.
3. To achieve automatic playback, the message mechanism is required, and the method of displaying the next picture is called at three seconds apart. Showing the next image is to call the setCurrentItem of the viewpager, passing in the number of items of the next image. The viewpager itself has functions when the fingers slide, so it does not need to be defined.
4. The final function to be implemented is that the text and small dots at the bottom of the viewpager change according to the picture. At this time, you can set a viewpager listening event, and change the value of the textview when the image changes. Then iterate through the subview of linearlayout (the subview is the small dots stored). When the serial number of the dot and the serial number of the picture are always the same, select the dot. Of course, we also need to take the remainder of the position here and convert the position to a range with the same size of the image.

Implementation of the main interface:

&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;RelativeLayout xmlns:andro
  xmlns:tools="/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:paddingBottom="@dimen/activity_vertical_margin"
  android:paddingLeft="@dimen/activity_horizontal_margin"
  android:paddingRight="@dimen/activity_horizontal_margin"
  android:paddingTop="@dimen/activity_vertical_margin"
  tools:context=""&gt;

  &lt;.
    android:
    android:layout_width="match_parent"
    android:layout_height="150dp" /&gt;

  &lt;LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignBottom="@id/view_pager"
    android:background="@color/trans_balck"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="5dp"&gt;

    &lt;TextView
      android:
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Picture Description"
      android:textColor="@android:color/white" /&gt;

    &lt;LinearLayout
      android:
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:orientation="horizontal"&gt;&lt;/LinearLayout&gt;
  &lt;/LinearLayout&gt;
&lt;/RelativeLayout&gt;

Status selector

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:andro>
  <item android:state_selected="true" android:drawable="@drawable/shape_dot_select"/>
  <item android:drawable="@drawable/shape_dot_normal"/>
</selector>

Drawing of shape diagram

&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;shape xmlns:andro
 android:shape="oval"&gt;
   &lt;solid android:color="@color/trans_balck"/&gt;
&lt;/shape&gt;

&lt;Save space, Write down two together&gt;
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;shape xmlns:andro
 android:shape="oval"&gt;
   &lt;solid android:color="@android:color/white"/&gt;
&lt;/shape&gt;

Business logic in the main program

import ;
import ;
import .;
import .;
import ;
import ;
import ;
import ;

public class MainActivity extends AppCompatActivity {
  private static final String TAG = "MainActivity";
  private int[] imageResids = {, , , , };
  private String[] desc = {
      "Gong Li is not vulgar, so I can't be vulgar",
      "The tree is back! Singing classic old songs to attract thousands of people to sing",
      "Revealing the secret of how Beijing movies are upgraded",
      "LeTV TV version delivery",
      "The hot-blooded loser's counterattack"
  };

  private LinearLayout ll_dots;
  private TextView tv_desc;
  private ViewPager viewpager;
  private static final int SHOW_NEXT_PAGE = 0;

  private Handler handler = new Handler() ;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    (savedInstanceState);
    setContentView(.activity_main);
    ll_dots = (LinearLayout) findViewById(.ll_dots);
    tv_desc = (TextView) findViewById(.tv_desc);
    viewpager = (ViewPager) findViewById(.view_pager);
    (new BannerAapter(imageResids));
    (listener);
    initDot();
    changeDotandDesc(0);
    (().getCount() / 2);
    (mRunnable,3000);
  }

  Runnable mRunnable = new Runnable() {
    @Override
    public void run() {
      shownextpage();
    }
  };
  /**Initialize small dots*/
  private void initDot() {
    for (int i = 0; i &lt; ; i++) {
      int _5dp = dp2px(5);
       params = new (_5dp, _5dp);
       = _5dp;
      View dot = new View(this);
      (params);
      (.select_dot);
      ll_dots.addView(dot);
    }
  }
  /**Convert pd data into px data*/
  private int dp2px(int pd) {
    float desity = getResources().getDisplayMetrics().density;
    return (int) (pd * desity + 0.5f);
  }

   listener = new () {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {
      changeDotandDesc(position);
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }
  };

  public void changeDotandDesc(int position) {
    position = position % ll_dots.getChildCount();
    tv_desc.setText(desc[position]);
    for (int i = 0; i &lt; ll_dots.getChildCount(); i++) {
      (TAG, "changeDotandDesc: " + i+ "  " + position);
      ll_dots.getChildAt(i).setSelected(i == position);
    }
  }

  private void shownextpage() {
    int currenItem = ();
    (currenItem + 1);
    (mRunnable,3000);
  }
}

Adapter writing:

import .;
import ;
import ;
import ;

/**
 * Created by huang on 2016/11/22.
 */
public class BannerAapter extends PagerAdapter {
  private int[] imageResIds;

  public BannerAapter(int[] imageResIds) {
     = imageResIds;
  }

  @Override
  public int getCount() {
    return  * 10000 * 100;
  }

  @Override
  public boolean isViewFromObject(View view, Object object) {
    return view == object;
  }

  @Override
  public Object instantiateItem(ViewGroup container, int position) {
    ImageView imageview = new ImageView(());
    position = position % ;
    (imageResIds[position]);
    (imageview);
    return imageview;
  }

  @Override
  public void destroyItem(ViewGroup container, int position, Object object) {
    ((ImageView) object);
  }
}

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.