編輯:關於android開發
自定義控件是根據自己的需要自己來編寫控件。安卓自帶的控件有時候無法滿足你的需求,這種時候,我們只能去自己去實現適合項目的控件。同時,安卓也允許你去繼承已經存在的控件或者實現你自己的控件以便優化界面和創造更加豐富的用戶體驗。在平常的項目中,我們 人為的把自定義控件分為兩種:一種是組合方式實現。一種是通過繼承view或viewgroup及其子類實現。兩者都可以實現我們想要的效果,因此,我們可以根據自己的需求,選擇合適的方案。本文以案例的形式來顯示幾種較為常見的自定義控件。
案例一: 優酷菜單
功能介紹: 手機界面的底部中央有一個半圓,初始狀態顯示三級菜單,由外到內分別是第三級菜單,第二級菜單,第三級菜單。每個菜單中有一些按鈕,可以用3個容器(RelativeLayout)來表示3個菜單,往裡面添加按鈕即可。當再次點擊中心位置的圖片式,隱藏外面兩層的的條目。再次點擊重心位置的圖片時,旋轉出二級菜單。點擊二級菜單中心位置時,旋轉出三級菜單,再次點擊則隱藏三級菜單。以上就是優酷菜單要實現的功能。
實現步驟:
1. 完成布局文件。由於控件較多所以優酷菜單的布局較為復雜,但是可以在一個根布局設置三個子線性布局來包裹每一個小的控件。通過調整margin值來是使得界面更加的美觀。注意3個菜單布局的順序,先放men3,然後menu2,然後menu1,順序不能反,因為越往後放的菜單越在界面的上方,這樣面積最小的菜單1會在最上方,菜單1不會遮擋到下面的菜單2和菜單3。
2. 完成布局文件後,創建一個類,在該類中實現業務邏輯。首先要創建兩個布爾類型的常量存儲菜單的狀態。通過swich語句判斷被點擊的控件是二級菜單還是一級菜單。如果是一級菜單的中心被點擊,則判斷三級菜單是否打開。如果三級菜單打開著,則隱藏一級菜單和二級菜單,並修改狀態。如果三級菜單隱藏著則判斷二級菜單是否隱藏。如果二級菜單打開著,則隱藏二級菜單。如果二級菜單隱藏則打開二級菜單。如果是二級菜單的中心被點擊,則只需要判斷三級菜單是否隱藏。如果三級菜單打開著,則隱藏三級菜單。如果三級菜單隱藏則打開三級菜單。同時還要修改菜單的狀態。
3. 接下來可以在一個工具類中實現動畫的效果。步驟2中的隱藏和顯示均都是通過動畫效果實現的。這裡的動畫效果用到的是補間動畫,為RotateAnimation對象傳入起始角度,結束的角度,參考對象和參考點坐標。一個小細節是將setFillAfter屬性設為true,表示從結束位置開始動畫,避免動畫結束後又回到起始位置。隱藏和顯示區別是旋轉的起始角度和結束角度,這裡顯示設定的起始角度是-180,結束角度為0。隱藏設定的起始角度為0,結束角度為-180。當然也可以設定為其他值,取決於自己想要的效果。
4. 代碼優化。快速點擊按鈕時會發現菜單還沒隱藏完就開始顯示了,或者還沒顯示完又隱藏了。解決方案:監聽動畫的開啟次數來判斷是否需要執行畫,給動畫類添加一個監聽器。設置一個成員變量。當開始開始動畫是執行加一操作,結束動畫是執行減一操作。這樣只有當常量為零時,才沒有動畫。因此swich語句中加入判斷如果當前存在動畫,等待動畫執行完之後在進入下面的邏輯。
菜單選擇界面的布局:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <RelativeLayout android:id="@+id/rl_menu3" 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:id="@+id/rl_menu2" 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:id="@+id/btn_menu2" 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:id="@+id/rl_menu1" android:layout_width="100dp" android:layout_height="50dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:background="@drawable/level1"> <ImageButton android:id="@+id/btn_menu1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:background="@drawable/icon_home" /> </RelativeLayout> </RelativeLayout>
主界面的布局,在代碼中用打氣筒把菜單布局打到主界面上。
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" tools:context="com.example.selectbar.Selectbar"> <com.example.selectbar.Rotate android:layout_centerInParent="true" android:id="@+id/rotate" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout>
主程序是空實現。
import android.os.Bundle; import android.support.v7.app.AppCompatActivity; public class Selectbar extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_selectbar); } }
主要邏輯的實現。
import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.widget.RelativeLayout; import com.example.selectbar.com.example.selectbar.utils.utils; /** * Created by huang on 2016/11/22. */ public class Rotate extends RelativeLayout implements View.OnClickListener { 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) { Log.i(TAG, "initdata: text"); View view = View.inflate(context,R.layout.activity_rolate,null); view.findViewById(R.id.btn_menu1).setOnClickListener(this); view.findViewById(R.id.btn_menu2).setOnClickListener(this); rl_menu1 = (RelativeLayout) view.findViewById(R.id.rl_menu1); rl_menu2 = (RelativeLayout) view.findViewById(R.id.rl_menu2); rl_menu3 = (RelativeLayout) view.findViewById(R.id.rl_menu3); addView(view); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_menu2: if (utils.hasAnimationexcuting()) { return; } if (menu3showing) { utils.hiden(rl_menu3); } else { utils.show(rl_menu3); } menu3showing = !menu3showing; break; case R.id.btn_menu1: if (utils.hasAnimationexcuting()) { return; } if (menu3showing) { utils.hiden(rl_menu3); menu3showing = false; utils.hiden(rl_menu2, 300); } else if (menu2showing) { utils.hiden(rl_menu2); } else { utils.show(rl_menu2); } menu2showing = !menu2showing; break; } } }
還需要一個工具類實現動畫的效果。
import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.RotateAnimation; /** * Created by huang on 2016/11/22. */ public class utils { private static final String TAG = "utils"; private static void setviewclickable(View view, boolean clickable) { view.setClickable(clickable); if (view instanceof ViewGroup) { ViewGroup viewgroup = (ViewGroup) view; for (int i = 0; i < viewgroup.getChildCount(); i++) { View child = ((ViewGroup) view).getChildAt(i); child.setClickable(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); ra.setDuration(500); ra.setFillAfter(true); ra.setStartOffset(startoffset); ra.setAnimationListener(listener); view.startAnimation(ra); } public static int startcount; static Animation.AnimationListener listener = new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { startcount++; // Log.i(TAG, "onAnimationStart: " +startcount); } @Override public void onAnimationEnd(Animation animation) { startcount--; // Log.i(TAG, "onAnimationEnd: " + startcount); } @Override public void onAnimationRepeat(Animation animation) { } }; }
案例二 popupwindow實現下拉列表:
功能介紹:創建一個textview,當我們點擊textview時會彈出一個列表,列表中存放的是數字信息和一張刪除圖片。列表是用listview實現。點擊刪除圖片可以將本條記錄從列表中刪除。本案例的有兩種,一種是通過動畫的縮放實現彈出效果,另一種是采取popupwindow。本文采用的是第二種方案。
實現步驟:
主界面的布局:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/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="com.example.popuwindow.MainActivity"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/et_number" android:layout_width="200dp" android:layout_height="wrap_content" android:hint="輸入賬號" /> <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" /> </RelativeLayout> </RelativeLayout>
listview條目的布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 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:id="@+id/tv_numer" 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:id="@+id/ib_del" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" android:src="@mipmap/delete" /> </LinearLayout>
單獨寫一個listview。
<?xml version="1.0" encoding="utf-8"?> <ListView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:cacheColorHint="@null" android:background="@mipmap/listview_background" android:descendantFocusability="blocksDescendants"> </ListView>
主程序中的邏輯。
import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.AdapterView; import android.widget.EditText; import android.widget.ListView; import android.widget.PopupWindow; public class MainActivity extends AppCompatActivity { private EditText et_number; private PopupWindow popupwindow; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_number = (EditText) findViewById(R.id.et_number); } public void showNumberListToggle(View view) { if (popupwindow == null) { //復用popupwindow View contentView = createContent(); int width = et_number.getWidth() - 4; int height = 400; boolean focusable = true; popupwindow = new PopupWindow(contentView, width, height, focusable); popupwindow.setBackgroundDrawable(new ColorDrawable()); } View anchor = et_number; int xoff = 2; int yoff = -5; popupwindow.showAsDropDown(anchor, xoff, yoff); } private View createContent() { ListView lv = (ListView) View.inflate(this, R.layout.activity_list, null); lv.setAdapter(new NumberListAdapter()); lv.setVerticalScrollBarEnabled(false); lv.setOnItemClickListener(monitemclickListener); return lv; } AdapterView.OnItemClickListener monitemclickListener = new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { String number = (String) parent.getItemAtPosition(position); et_number.setText(number); popupwindow.dismiss(); } }; }
適配器的編寫
import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import java.util.ArrayList; /** * 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++) { numbers.add(10000 + i + "" ); } } @Override public int getCount() { return numbers.size(); } @Override public Object getItem(int position) { return numbers.get(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 = View.inflate(parent.getContext(),R.layout.item_number_list,null); holder = new viewHolder(); holder.ib_del = (ImageView) view.findViewById(R.id.ib_del); holder.tv_number = (TextView) view.findViewById(R.id.tv_numer); view.setTag(holder); }else{ view = convertView; holder = (viewHolder)view.getTag(); } holder.ib_del.setImageResource(R.mipmap.delete); holder.tv_number.setText(numbers.get(position)); holder.ib_del.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { numbers.remove(position); notifyDataSetChanged(); } }); return view; } static class viewHolder{ TextView tv_number; ImageView ib_del; } }
案例三 viewpager實現輪播圖:
功能介紹: 廣告條的實現,又被稱為輪播圖。在手機界面的最上方放置一個ViewPager功能,實現界面的左右滑動。滑動又分為兩種,一種是間隔一定的時間自動滑動,同時還支持手勢的左右滑動。一個小細節是在輪播圖底部放置和圖片數量相等的小點,用於表示當前哪個圖片被選中。
實現步驟:
1. 布局文件有兩部分組成,一個是viewpager,一個是底部的條和小圓點。Viewpager存在於v4包下,因此可兼容到Android1.6。底部的條和小圓點放在一個線性布局中,讓放在viewpager的底部,同時文字和圓點為中心位置。這裡特別說一下小圓點的實現。小圓點使用shape圖做出來的。由於無法再布局文件中獲取圓點的個數,因此可以在布局文件中放置一個LinearLayout,然後在java代碼中將view對象向該LinearLayout中添加。同時將白點和黑點的狀態選擇器設置為view的背景。
2. 接下來是viewpager的編寫。編寫viewpager的關鍵是寫適配器。寫一個類繼承PagerAdapter,重寫其中的方法。Viewpager默認是加載三張圖片,屏幕中間一張,屏幕左邊和屏幕右邊各一張。我們希望輪播圖能夠循環的播放,因此可以給getcount返回一個足夠大的值,初始化輪播圖時,將輪播圖的初始位置設置在中間,這樣就可以實現循環播放。當我們把getcount返回值設為一個很大的值時,在instantiateItem中也要對position進行判斷。傳入的的position是一個極大的值,但是圖片的數量確實有限的,因此可以對position取余,這樣就可以把position的位置和圖片的數量對應起來。
3. 實現自動播放需要用到消息機制,間隔三秒調用顯示下一張圖片的方法。顯示下一張圖片是調用viewpager的setCurrentItem,傳入下一個圖片的item數。手指滑動時viewpager自身就有的功能,因此不需要再定義。
4. 最後要實現的功能是,viewpager底部的文字和小圓點跟隨圖片變化。這時候可以設定一個viewpager的監聽事件,當圖片發生改變時改變textview的值。然後遍歷linearlayout的子view(子view中存發的是小圓點),當圓點的序列號和圖片的序列號一直是,則選中圓點。當然,這裡同樣要對position取余,將position轉化到於圖片大小一致的范圍。
主界面的實現:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/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="com.example.advertisement.MainActivity"> <android.support.v4.view.ViewPager android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="150dp" /> <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"> <TextView android:id="@+id/tv_desc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="圖片描述" android:textColor="@android:color/white" /> <LinearLayout android:id="@+id/ll_dots" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"></LinearLayout> </LinearLayout> </RelativeLayout>
狀態選擇器
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_selected="true" android:drawable="@drawable/shape_dot_select"/> <item android:drawable="@drawable/shape_dot_normal"/> </selector>
shape圖的繪制
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <solid android:color="@color/trans_balck"/> </shape> <節省空間, 兩個寫下一起> <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <solid android:color="@android:color/white"/> </shape>
主程序中的業務邏輯
import android.os.Bundle; import android.os.Handler; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private int[] imageResids = {R.drawable.a, R.drawable.b, R.drawable.c, R.drawable.d, R.drawable.e}; private String[] desc = { "鞏俐不低俗,我就不能低俗", "撲樹又回來啦!再唱經典老歌引萬人大合唱", "揭秘北京電影如何升級", "樂視網TV版大派送", "熱血屌絲的反殺" }; 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) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ll_dots = (LinearLayout) findViewById(R.id.ll_dots); tv_desc = (TextView) findViewById(R.id.tv_desc); viewpager = (ViewPager) findViewById(R.id.view_pager); viewpager.setAdapter(new BannerAapter(imageResids)); viewpager.setOnPageChangeListener(listener); initDot(); changeDotandDesc(0); viewpager.setCurrentItem(viewpager.getAdapter().getCount() / 2); handler.postDelayed(mRunnable,3000); } Runnable mRunnable = new Runnable() { @Override public void run() { shownextpage(); } }; /**初始化小圓點*/ private void initDot() { for (int i = 0; i < imageResids.length; i++) { int _5dp = dp2px(5); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(_5dp, _5dp); params.leftMargin = _5dp; View dot = new View(this); dot.setLayoutParams(params); dot.setBackgroundResource(R.drawable.select_dot); ll_dots.addView(dot); } } /**將pd數據轉化為px數據*/ private int dp2px(int pd) { float desity = getResources().getDisplayMetrics().density; return (int) (pd * desity + 0.5f); } ViewPager.OnPageChangeListener listener = new ViewPager.OnPageChangeListener() { @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 < ll_dots.getChildCount(); i++) { Log.i(TAG, "changeDotandDesc: " + i+ " " + position); ll_dots.getChildAt(i).setSelected(i == position); } } private void shownextpage() { int currenItem = viewpager.getCurrentItem(); viewpager.setCurrentItem(currenItem + 1); handler.postDelayed(mRunnable,3000); } }
適配器的編寫:
import android.support.v4.view.PagerAdapter; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; /** * Created by huang on 2016/11/22. */ public class BannerAapter extends PagerAdapter { private int[] imageResIds; public BannerAapter(int[] imageResIds) { this.imageResIds = imageResIds; } @Override public int getCount() { return imageResIds.length * 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(container.getContext()); position = position % imageResIds.length; imageview.setBackgroundResource(imageResIds[position]); container.addView(imageview); return imageview; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((ImageView) object); } }
Android Picasso 獲取遠程圖片並顯示, Picasso是Square公司開源的一個Android圖形緩存庫,地址http://square.git
Android Studio安裝與使用,androidstudio安裝 2013年谷歌推出android studio後,單獨支持android開發,這是基於Java語
XAMARIN.ANDROID SIGNALR 實時消息接收發送示例,xamarinsignalrSignalR 是一個開發實時 Web 應用的 .NET 類庫,使用 S
單機搭建Android開發環境(三),單機搭建android開發單機搭建Android開發環境,第一篇重點介紹了如何優化Windows 7系統,以提高開發主機的性能並延長