Recently, I made a small function to achieve the effect similar to gallery. However, you need to select the first item and do not want to move it to the very beginning to have free space, if you try to use the gallery that comes with android, you can write something simple but functional. First, share the usage of gallery.
The first problem is that you do not want to pull the leading blank. Therefore, refer to the online example and select a large number through setselection settings. Of course, the maximum value of int must be returned in the getcount method in the adapter. The code in getview is as follows. cacheView is a HashMap <Integer, View> object in the cache itemview defined in the class, then use position % list. size () to obtain the view that is already in the cache, where list is the data collection of the data source.
ConvertView = cacheView. get (position % list. size ());
If (convertView = null ){
ConvertView = mInflater. inflate (layoutId, null );
ImageView iv = (ImageView) convertView. findViewById (R. id. image );
Iv. setBackgroundResource (list. get (position % list. size ()));
CacheView. put (position % list. size (), convertView );
}
Return convertView;
In this way, the screen is full at the beginning, and the left and right sides are displayed cyclically, but the selected items are still in the middle. When the drag ends,
Since the above cannot meet the requirements, I tried to inherit the onTouchEvent and onFling method in gallery rewriting, which can be passed through MotionEvent. ACTION_UP and onFling directly return false; when the drag is reached, it is not automatically selected, but the Click Event of the item cannot be used, that is, OnItemClickListener cannot be triggered. After a long time, give up
On the Internet, I saw someone put forward an idea of using ScrollView to implement gallery. So I wrote a simple but easy-to-use code. I would like to share with you some ideas.
Public class MyGallery extends HorizontalScrollView {
Public MyGallery (Context context, AttributeSet attrs ){
Super (context, attrs );
}
Public MyGallery (Context context, AttributeSet attrs, int defStyle ){
Super (context, attrs, defStyle );
}
Private List <ImageView> imageViews = new ArrayList <ImageView> (); // Image view object, which is generated after initialization.
Private List <TextView> textViews = new ArrayList <TextView> (); // text view object, which is generated after Initialization
Private Context mContext; // call the activity of this view
Private int mWidth; // value in onlayout
Private int selectedItemIndex =-1; // The subscript of the selected item
Private int displayNum = 5; // number of items to be displayed
Private int defaultIndex = 0; // The default subscript.
Private int itemWidth; // The width of each item
Private OnClickListener itemClickListener; // click the event of each item and initialize the input. postion can be distinguished by the tag in the view in onclick.
Private Handler handler; // used to process selected rolling events
Private int inoutTime = 200; // zoom in and out the time consumed
Private float scale = 1.2f; // The scaled-up ratio.
Private LayoutInflater mInflater;
Private List <IWantType> typeList; // category List
Private int adjust =-5; // adjust the Moving position
Public MyGallery (Context context ){
Super (context );
This. mContext = context;
}
/**
* When the layout is completed, the item layout is initialized Based on the width and displayed quantity.
*/
@ Override
Protected void onLayout (boolean changed, int l, int t, int r, int B ){
Super. onLayout (changed, l, t, r, B );
If (this. mWidth! = This. getWidth ()){
This. mWidth = this. getWidth ();
This. itemWidth = this. mWidth/this. displayNum;
InitImages (itemClickListener );
}
}
/**
* Initialization
* @ Param context
* @ Param images
* @ Param itemClickListener
*/
Public void init (Context context, List <IWantType> typeList, OnClickListener itemClickListener, int defaultIndex ){
This. typeList = typeList;
This. mContext = context;
This. mInflater = LayoutInflater. from (context );
This. defaultIndex = defaultIndex;
This. setVerticalScrollBarEnabled (false); // disable vertical scrolling.
This. setHorizontalScrollBarEnabled (false); // disable horizontal scrolling.
This. itemClickListener = itemClickListener;
This. handler = new Handler (){
Public void handleMessage (Message msg ){
If (msg. arg1> msg. arg2 ){
Int each = (msg. arg1-msg.arg2)/10;
If (msg. arg2 + each <msg. arg1 & each> 0 ){
ScrollTo (msg. arg2 + each + adjust, 0 );
} Else {
ScrollTo (msg. arg1 + adjust, 0 );
}
Message message = new Message ();
Message. arg1 = msg. arg1;
If (each! = 0 ){
Message. arg2 = msg. arg2 + each;
SendMessageDelayed (message, 1 );
}
} Else {
Int each = (msg. arg2-msg.arg1)/10;
If (msg. arg2-each> msg. arg1 & each> 0 ){
Scrolling to (msg. arg2-each + adjust, 0 );
} Else {
ScrollTo (msg. arg1 + adjust, 0 );
}
Message message = new Message ();
Message. arg1 = msg. arg1;
If (each! = 0 ){
Message. arg2 = msg. arg2-each;
SendMessageDelayed (message, 1 );
}
}
};
};
}
/**
* Bind an image item
* @ Param clickListener
*/
Private void initImages (OnClickListener clickListener ){
This. removeAllViews ();
LinearLayout ll = new LinearLayout (mContext );
Ll. setLayoutParams (new LayoutParams (LayoutParams. FILL_PARENT, LayoutParams. WRAP_CONTENT ));
For (int I = 0; I <typeList. size (); I ++ ){
IWantType iWantType = typeList. get (I );
FrameLayout llitem = (FrameLayout) mInflater. inflate (R. layout. mygallery_item, null );
Llitem. setLayoutParams (new RelativeLayout. LayoutParams (this. itemWidth, LayoutParams. WRAP_CONTENT ));
ImageView image = (ImageView) llitem. findViewById (R. id. image );
Image. setTag (I );
Image. setOnClickListener (clickListener );
TextView textView = (TextView) llitem. findViewById (R. id. text );
TextView. setText (iWantType. name );
TextView. setTextColor (Color. parseColor (iWantType. color ));
NeighborApplication. getSelf (). getPictrueManager (). download (iWantType. pic, image );
Ll. addView (llitem );
ImageViews. add (image );
TextViews. add (textView );
}
This. addView (ll );
SelectItem (defaultIndex );
}
/**
* Obtain an imageView
* @ Param postion
* @ Return
*/
Public ImageView getItemView (int postion ){
Return imageViews. get (postion );
}
/**
* Select an item
* @ Param position
*/
Public void selectItem (Integer position ){
If (position! = SelectedItemIndex ){
If (selectedItemIndex! =-1 ){
ImageViews. get (selectedItemIndex). startAnimation (scaleIn (inoutTime ));
TextViews. get (selectedItemIndex). startAnimation (scaleIn (inoutTime ));
}
ImageViews. get (position). startAnimation (scaleOut (inoutTime ));
TextViews. get (position). startAnimation (scaleOut (inoutTime ));
SelectedItemIndex = position;
Message msg = new Message ();
Msg. arg1 = position * itemWidth;
Msg. arg2 = getScrollX ();
This. handler. sendMessage (msg );
}
}
/**
* Select next
* @ Return the selected index
*/
Public int selectNext (){
If (selectedItemIndex + 1 <imageViews. size ()){
SelectItem (selectedItemIndex + 1 );
}
Return selectedItemIndex;
}
/**
* Select the previous one.
* @ Return the selected index
*/
Public int selectPrev (){
If (selectedItemIndex> 0 ){
SelectItem (selectedItemIndex-1 );
}
Return selectedItemIndex;
}
/**
* Expand with itself centered
* @ Param duration
* @ Return
*/
Private Animation scaleOut (long time ){
Animation animation = new ScaleAnimation (1, scale, 1, scale, Animation. RELATIVE_TO_SELF, 0.5f, Animation. RELATIVE_TO_SELF, 0.5f );
Animation. setDuration (time );
Animation. setFillAfter (true );
Return animation;
}
/**
* Shrink from the center of itself
* @ Param duration
* @ Return
*/
Private Animation scaleIn (long time ){
Animation animation = new ScaleAnimation (scale, 1, scale, 1, Animation. RELATIVE_TO_SELF, 0.5f, Animation. RELATIVE_TO_SELF, 0.5f );
Animation. setDuration (time );
Return animation;
}
The iwanttype class is an entity class. You can change it based on your needs. It is mainly used to bind data to items.
<? Xml version = "1.0" encoding = "UTF-8"?>
<FrameLayout xmlns: android = "http://schemas.android.com/apk/res/android"
Android: orientation = "vertical"
Android: layout_width = "wrap_content"
Android: layout_height = "wrap_content"
>
<ImageView
Android: id = "@ + id/image"
Android: layout_width = "wrap_content"
Android: layout_height = "wrap_content"
Android: layout_centerInParent = "true"
/>
<TextView
Android: id = "@ + id/text"
Android: layout_width = "wrap_content"
Android: layout_height = "wrap_content"
Android: layout_gravity = "center_horizontal"
Android: layout_marginTop = "60dip"
/>
</FrameLayout>
The above is the layout file of the item. It is just an image and the text below. Because I want to overwrite a part of the image here, framelayout is used. You can use it as needed.
The general idea is to insert imageview and textview cyclically in a LinearLayout based on the data source, and bind click events according to the externally passed click events. Note that, when writing the onclick method by yourself, it is convenient to distinguish each item = from itemclick according to the getTag of the view .. But it can still be used. The selected items here are at the beginning. You can also modify the control scrolling code in handler as needed, this simple and practical gallery is complete ~~~
From chenghaoorange's column