最近,根據項目需求,需要一個能夠自動分頁的導航,所以便自定義了一個自動分頁的GridView。
思路:繼承RelativeLayout,然后在里面放了一個viewpager和一個GridView。。。我也不會說,還是直接上代碼吧
先看看你效果圖,分別是2行3列和1行3列(有自定義屬性,可以自己定義幾行幾列)
接下來直接看源代碼(很簡單)
1 package custom.widget; 2 3 import android.annotation.TargetApi; 4 import android.content.Context; 5 import android.content.res.TypedArray; 6 import android.os.Build; 7 import android.support.v4.view.PagerAdapter; 8 import android.support.v4.view.ViewPager; 9 import android.util.AttributeSet; 10 import android.view.MotionEvent; 11 import android.view.View; 12 import android.view.ViewGroup; 13 import android.widget.AbsListView; 14 import android.widget.AdapterView; 15 import android.widget.BaseAdapter; 16 import android.widget.GridView; 17 import android.widget.LinearLayout; 18 import android.widget.RadioButton; 19 import android.widget.RadioGroup; 20 import android.widget.RelativeLayout; 21 22 import com.newair.automaticpagedemo.R; 23 24 import java.util.ArrayList; 25 import java.util.List; 26 27 /** 28 * Created by ouhimehime on 16/5/4. 29 * ----------自動分頁的GridView---------- 30 */ 31 public class AutoMaticPageGridView extends RelativeLayout { 32 33 //分頁所用 34 private ViewPager viewPager; 35 //導航點 36 private RadioGroup radioGroup; 37 //自定義行數 38 private int lines = 0; 39 //自定義列數 40 private int column = 0; 41 //自定義按鈕樣式 42 private int btn_res; 43 //自定義屬性是否顯示導航點 44 private boolean btn_isvisible; 45 //頁數-需要動態計算 46 private int pages = 0; 47 //適配器 48 private BaseAutoAdapter adapter; 49 //Item的高度 50 private int itemHeight = 0; 51 52 //點擊事件的接口 53 public interface OnItemClickCallBack { 54 void OnItemClicked(int position, Object object); 55 } 56 57 private OnItemClickCallBack onItemClickCallBack; 58 59 public void setOnItemClickListener(OnItemClickCallBack onItemClickCallBack) { 60 this.onItemClickCallBack = onItemClickCallBack; 61 } 62 63 64 public AutoMaticPageGridView(Context context) { 65 super(context); 66 } 67 68 public AutoMaticPageGridView(Context context, AttributeSet attrs) { 69 super(context, attrs); 70 init(context, attrs); 71 } 72 73 public AutoMaticPageGridView(Context context, AttributeSet attrs, int defStyleAttr) { 74 super(context, attrs, defStyleAttr); 75 init(context, attrs); 76 } 77 78 @TargetApi(Build.VERSION_CODES.LOLLIPOP) 79 public AutoMaticPageGridView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 80 super(context, attrs, defStyleAttr, defStyleRes); 81 init(context, attrs); 82 } 83 84 85 //初始化控件 86 private void init(Context context, AttributeSet attrs) { 87 //加載自定義屬性 88 final TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.AutoMaticPageGridView); 89 lines = array.getInteger(R.styleable.AutoMaticPageGridView_auto_lines, 1);//行數 90 column = array.getInteger(R.styleable.AutoMaticPageGridView_auto_column, 4);//列數 91 btn_res = array.getResourceId(R.styleable.AutoMaticPageGridView_auto_button, 0);//btn的樣式 92 btn_isvisible = array.getBoolean(R.styleable.AutoMaticPageGridView_auto_button_visible, true);//默認true 93 array.recycle(); 94 //分頁用 95 viewPager = new ViewPager(context); 96 viewPager.setLayoutParams(new LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, 97 RelativeLayout.LayoutParams.MATCH_PARENT)); 98 addView(viewPager); 99 //導航點用 100 radioGroup = new RadioGroup(context); 101 radioGroup.setOrientation(LinearLayout.HORIZONTAL); 102 RelativeLayout.LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); 103 params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); 104 params.addRule(RelativeLayout.CENTER_IN_PARENT); 105 radioGroup.setLayoutParams(params); 106 addView(radioGroup); 107 //如果不顯示的話就隱藏 108 if (!btn_isvisible) { 109 radioGroup.setVisibility(GONE); 110 } 111 } 112 113 //設置適配器 114 public void setAdapter(BaseAutoAdapter baseAdapter) { 115 this.adapter = baseAdapter; 116 //計算頁數 117 if ((adapter.getCounts() / (column * lines)) > 0) { 118 pages = (adapter.getCounts() / (column * lines)) + 1; //多一頁 119 } else { 120 pages = adapter.getCounts(); 121 } 122 //添加radioButton 123 addRadioButton(pages); 124 this.post(new Runnable() { 125 @Override 126 public void run() { 127 itemHeight = getMeasuredHeight() / lines; 128 //顯示viewpager 129 ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getContext()); 130 viewPager.setAdapter(viewPagerAdapter); 131 //設置聯動 132 initLinkAgeEvent(); 133 } 134 }); 135 } 136 137 //添加RadioButton 138 private void addRadioButton(int pages) { 139 for (int i = 0; i < pages; i++) { 140 RadioButton radioButton = new RadioButton(getContext()); 141 radioButton.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, 142 LinearLayout.LayoutParams.WRAP_CONTENT)); 143 radioButton.setPadding(5, 5, 5, 5);//間距 144 radioButton.setId(i);//設置Id,方便聯動 145 radioButton.setClickable(false); 146 if (btn_res != 0) { //設置按鈕樣式 147 radioButton.setButtonDrawable(btn_res); 148 } 149 radioGroup.addView(radioButton); 150 } 151 } 152 153 //給當前頁計算數據數量 154 private List<View> getAdapterData(int position) { 155 List<View> cerrent = new ArrayList<>(); 156 if (position == pages - 1) { //如果等於最后一頁 157 for (int i = position * (lines * column); i < adapter.getCounts(); i++) { 158 cerrent.add(adapter.getItemView(i, null)); 159 } 160 } else { 161 for (int i = position * (lines * column); i < position * (lines * column) + (lines * column); i++) { 162 cerrent.add(adapter.getItemView(i, null)); 163 } 164 } 165 return cerrent; 166 } 167 168 //ViewPager適配器 169 private class ViewPagerAdapter extends PagerAdapter { 170 171 private Context context; 172 173 public ViewPagerAdapter(Context context) { 174 this.context = context; 175 } 176 177 @Override 178 public int getCount() { 179 return pages; 180 } 181 182 @Override 183 public boolean isViewFromObject(View view, Object object) { 184 return view == object; 185 } 186 187 @Override 188 public Object instantiateItem(ViewGroup container, int position) { 189 CustomGridView gridView = new CustomGridView(context); 190 gridView.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, 191 AbsListView.LayoutParams.MATCH_PARENT)); 192 gridView.setNumColumns(column);//設置列數 193 gridView.setColumnWidth(GridView.AUTO_FIT); 194 GridViewAdapter adapter = new GridViewAdapter(getAdapterData(position), position); 195 gridView.setAdapter(adapter); 196 container.addView(gridView); 197 gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 198 @Override 199 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 200 GridViewAdapter adapter1 = (GridViewAdapter) parent.getAdapter(); 201 onItemClickCallBack.OnItemClicked(adapter1.currentPage * (lines * column) + position, view); 202 } 203 }); 204 return gridView; 205 } 206 207 @Override 208 public void destroyItem(ViewGroup container, int position, Object object) { 209 container.removeView((GridView) object); 210 } 211 } 212 213 //GridView的適配器 214 private class GridViewAdapter extends BaseAdapter { 215 216 private List<View> views;//數據量 217 public int currentPage; //當前頁 218 219 public GridViewAdapter(List<View> counts, int currentPage) { 220 this.views = counts; 221 this.currentPage = currentPage; 222 } 223 224 @Override 225 public int getCount() { 226 return views.size(); 227 } 228 229 @Override 230 public Object getItem(int position) { 231 return position; 232 } 233 234 @Override 235 public long getItemId(int position) { 236 return position; 237 } 238 239 @Override 240 public View getView(int position, View convertView, ViewGroup parent) { 241 if (convertView == null) { 242 convertView = views.get(position); 243 convertView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, itemHeight)); 244 } 245 return convertView; 246 } 247 248 } 249 250 //自定義GridView,禁止滑動 251 private class CustomGridView extends GridView { 252 253 public CustomGridView(Context context) { 254 super(context); 255 } 256 257 public CustomGridView(Context context, AttributeSet attrs) { 258 super(context, attrs); 259 } 260 261 public CustomGridView(Context context, AttributeSet attrs, int defStyleAttr) { 262 super(context, attrs, defStyleAttr); 263 } 264 265 @TargetApi(Build.VERSION_CODES.LOLLIPOP) 266 public CustomGridView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 267 super(context, attrs, defStyleAttr, defStyleRes); 268 } 269 270 @Override 271 public boolean dispatchTouchEvent(MotionEvent ev) { 272 if (ev.getAction() == MotionEvent.ACTION_MOVE) { 273 return true;//禁止GridView進行滑動 274 } 275 return super.dispatchTouchEvent(ev); 276 } 277 } 278 279 //初始化聯動聯動事件 280 private void initLinkAgeEvent() { 281 //默認選中第一個 282 viewPager.setCurrentItem(0); 283 radioGroup.check(radioGroup.getChildAt(0).getId()); 284 //滑動換頁事件 285 viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { 286 @Override 287 public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 288 289 } 290 291 @Override 292 public void onPageSelected(int position) { 293 radioGroup.check(position); 294 } 295 296 @Override 297 public void onPageScrollStateChanged(int state) { 298 299 } 300 }); 301 } 302 303 }
這個組件也有個適配器,很簡單,就是定義了幾個抽象方法
package custom.widget; import android.view.View; import android.view.ViewGroup; /** * Created by ouhimehime on 16/5/4. * -----適配器=------ */ public abstract class BaseAutoAdapter { public abstract int getCounts(); //返回數據數量 public abstract Object getItem(int position); //當前Item的數據 public abstract View getItemView(int position, ViewGroup parent); //返回Item的布局 }
還自定義了一部分屬性,方便使用起來好控制
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="AutoMaticPageGridView"> <!-- 行數 --> <attr name="auto_lines" format="integer" /> <!-- 列數 --> <attr name="auto_column" format="integer" /> <!-- button的樣式 --> <attr name="auto_button" format="reference" /> <!-- 是否顯示導航點 --> <attr name="auto_button_visible" format="boolean" /> </declare-styleable> </resources>
-----------------------------------------------------------------------以上就是源代碼了-----------------------------------------------------------------------------
下面是如何使用:(就當做一個控件來使用就可以)
①、先看布局文件XML,控件的高度是可以自己定義的
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:auto="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:orientation="vertical" tools:context=".MainActivity"> <custom.widget.AutoMaticPageGridView android:id="@+id/automatic" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" auto:auto_button="@drawable/btn_status_style" auto:auto_column="3" auto:auto_lines="2" /> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="2"/> </LinearLayout>
②、再看適配器代碼,適配器需要繼承BaseAutoAdapter
package adapter; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.newair.automaticpagedemo.R; import java.util.List; import custom.widget.BaseAutoAdapter; /** * Created by ouhimehime on 16/5/4. * ------------適配器------------ */ public class MyAutoMaticPageAdapter extends BaseAutoAdapter { private Context context; private List<Integer> myData; public MyAutoMaticPageAdapter(Context context, List<Integer> myData) { this.context = context; this.myData = myData; } @Override public int getCounts() { return myData.size(); } @Override public Object getItem(int position) { return myData.get(position); } @Override public View getItemView(int position, ViewGroup parent) { View view = LayoutInflater.from(context).inflate(R.layout.item_layout, null); return view; } }
③、再看主布局代碼,為了方便我就隨便放了放了10條數據
package com.newair.automaticpagedemo; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.Toast; import java.util.ArrayList; import java.util.List; import adapter.MyAutoMaticPageAdapter; import custom.widget.AutoMaticPageGridView; public class MainActivity extends AppCompatActivity { private AutoMaticPageGridView automatic; private MyAutoMaticPageAdapter adapter; private List<Integer> myData; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); automatic = (AutoMaticPageGridView) findViewById(R.id.automatic); myData = new ArrayList<>(); for (int i = 0; i < 10; i++) { myData.add(i); } adapter = new MyAutoMaticPageAdapter(this, myData); automatic.setAdapter(adapter); //點擊事件 automatic.setOnItemClickListener(new AutoMaticPageGridView.OnItemClickCallBack() { @Override public void OnItemClicked(int position, Object object) { Toast.makeText(MainActivity.this, position + "--", Toast.LENGTH_SHORT).show(); } }); } }
------------------------------------------------------------------------以上是如何使用----------------------------------------------------------------------------------
以上就是自己定義了一個自動分頁的控件,寫的不好,希望各位見諒。