編輯:關於Android編程
效果:滑動切換,自動切換。
代碼:https://github.com/ldb-github/Layout_Tab
1、布局界面通過ViewPager標簽來實現視圖左右切換。
2、然後通過LinearLayout增加指示器功能,表明當前展示的是第幾個視圖;其中指示器是通過兩種小圓點圖片來表示未顯示和顯示兩種狀態。
viewpager_pageradapter.xml
1、在原文的基礎上
a、增加了isSlipped控制手動滑動後當前顯示圖片currentIndex與自動輪播what不一致問題。
b、增加isRunning控制退出Activity後,輪播線程繼續在執行的問題。
2、ViewPager與PagerAdapter的一點關系:
viewPager.setCurrentItem() --> viewPager.populate() --> viewPager.addNewItem() --> adapter.instantiateItem()
public class ViewPagerAndPagerAdapterActivity extends Activity{ private static final String LOG_TAG = ViewPagerAndPagerAdapterActivity.class.getSimpleName(); private ViewPager viewPager; private ArrayListViewPagerAndPagerAdapterActivity.javalist = new ArrayList<>(); // 底部點的布局 private LinearLayout pointLayout; // 底部的點 private ImageView[] dots; // 當前選中的索引 private int currentIndex; private boolean flag = true; // 自增int private AtomicInteger what = new AtomicInteger(0); private boolean isSlipped; // 控制循環播放圖片線程 private boolean isRunning; private PagerAdapter pagerAdapter = new PagerAdapter() { @Override public int getCount() { Log.d(LOG_TAG, "In PagerAdapter.getCount()"); return list.size(); } @Override public boolean isViewFromObject(View view, Object object) { Log.d(LOG_TAG, "In PagerAdapter.isViewFromObject()"); return view == object; } // viewPager.setCurrentItem() --> viewPager.populate() --> viewPager.addNewItem() // --> adapter.instantiateItem() // 在ViewPager.addNewItem()方法中調用 @Override public Object instantiateItem(ViewGroup container, int position) { Log.d(LOG_TAG, "In PagerAdapter.instantiateItem()"); container.addView(list.get(position)); return list.get(position); } @Override public void destroyItem(ViewGroup container, int position, Object object) { Log.d(LOG_TAG, "In PagerAdapter.destroyItem()"); container.removeView(list.get(position)); } }; private final Handler viewHandler = new Handler(){ @Override public void handleMessage(Message msg) { Log.d(LOG_TAG, "In Handler.handleMessage start"); viewPager.setCurrentItem(msg.what); Log.d(LOG_TAG, "In Handler.handleMessage stop"); setDots(msg.what); } }; @Override protected void onCreate(Bundle savedInstanceState) { Log.d(LOG_TAG, "In onCreate"); super.onCreate(savedInstanceState); setContentView(R.layout.viewpager_pageradapter); init(); initDots(); } @Override protected void onStart() { Log.d(LOG_TAG, "In onStart"); super.onStart(); } @Override protected void onResume() { Log.d(LOG_TAG, "In onResume"); super.onResume(); isRunning = true; loopPlay(); } @Override protected void onPause() { Log.d(LOG_TAG, "In onPause"); super.onPause(); } @Override protected void onStop() { Log.d(LOG_TAG, "In onStop"); super.onStop(); isRunning = false; } @Override protected void onDestroy() { Log.d(LOG_TAG, "In onDestroy"); super.onDestroy(); } private void init(){ isSlipped = false; viewPager = (ViewPager) findViewById(R.id.first_vp); LayoutInflater inflater = LayoutInflater.from(this); View view1 = inflater.inflate(R.layout.viewpager_pageradapter_tab1, null); View view2 = inflater.inflate(R.layout.viewpager_pageradapter_tab2, null); View view3 = inflater.inflate(R.layout.viewpager_pageradapter_tab3, null); View view4 = inflater.inflate(R.layout.viewpager_pageradapter_tab4, null); list.add(view1); list.add(view2); list.add(view3); list.add(view4); viewPager.setAdapter(pagerAdapter); // setOnPageChangeListener 棄用了 viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { Log.d(LOG_TAG, "In OnPageChangeListener.onPageScrolled"); } @Override public void onPageSelected(int position) { Log.d(LOG_TAG, "In OnPageChangeListener.onPageSelected"); isSlipped = true; setDots(position); } @Override public void onPageScrollStateChanged(int state) { Log.d(LOG_TAG, "In OnPageChangeListener.onPageScrollStateChanged"); } }); } /** * 初始化底部的點 */ private void initDots(){ pointLayout = (LinearLayout) findViewById(R.id.point_layout); dots = new ImageView[list.size()]; for(int i = 0; i < list.size(); i++){ dots[i] = (ImageView) pointLayout.getChildAt(i); } currentIndex = 0; dots[currentIndex].setBackgroundResource(R.drawable.dian_down); } /** * 當滾動時更換點的背景圖 */ private void setDots(int position){ if(position < 0 || position > list.size() - 1 || currentIndex == position){ return; } dots[position].setBackgroundResource(R.drawable.dian_down); dots[currentIndex].setBackgroundResource(R.drawable.dian); currentIndex = position; } /** * 循環播放圖片 */ private void loopPlay() { /** * 開辟線程來控制圖片左右輪播 */ new Thread(new Runnable() { @Override public void run() { Log.d(LOG_TAG, "Runnable.run isRunning = " + isRunning); while (isRunning) { Log.d(LOG_TAG, "In loopPlay.run isSlipped = " + isSlipped); Log.d(LOG_TAG, "In loopPlay.run currentIndex = " + currentIndex); // 處理手動滑動的情況 if (isSlipped) { isSlipped = false; Log.d(LOG_TAG, "In loopPlay.run isSlipped was recovered "); what.set(currentIndex); } viewHandler.sendEmptyMessage(what.get()); if (what.get() >= list.size() - 1) { flag = false; } if (what.get() < 1) { flag = true; } if (flag) { what.incrementAndGet(); } else { what.decrementAndGet(); } try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } }
這篇來介紹一下適配器模式(Adapter Pattern),適配器模式在開發中使用的頻率也是很高的,像 ListView 和 RecyclerView 的 Adapter
前言最近要實現個圓角邊框的對話框設計圖,查了網上很多種實現,都差不多,從中得到靈感,實現了另一種方式,利用layer-list:先來看看實現的效果如下:首先在drawab
直接上效果圖: 實現步驟: 1.主界面activity_main.xml很簡單,一個按鈕 2.彈出層樣式actionsheet.xml
由於移動設備物理顯示空間一般有限,不可能一次性的把所有要顯示的內容都顯示在屏幕上。所以各大平台一般會提供一些可滾動的視圖來向用戶展示數據。Android平台框架中為我們提