androidgridview非同步
⑴ 如何設置 android gridview 怎麼設置 , 一些item可以點擊,另外.....
這個要在代碼中進行設置,基本上有兩種方式:
在GridView所在的 activity(或者fragment)中, 找到該View,監聽點擊事件:
java">gridView.setOnItemClickListener(newAdapterView.OnItemClickListener(){
@Override
publicvoidonItemClick(AdapterView<?>parent,Viewview,intposition,longid){
//點擊item觸發,進行判斷,如果需要處理點擊,就進行處理,否則,什麼也不做
if(/*處理點擊條件*/){
//要做的事
}
}
});在自己寫的GridView對應的適配器中(一般繼承於BaseAdapter)的getView中進行判斷,如果是需呀處理的item, 就調用setOnClickListener,並定義相應的點擊事件,否則可以不綁定點擊事件。
⑵ Android中GridView如何與廣告位輪播實現一起滑動
1.首先自定義一個ViewFlow類。
2.然後定義一個CircleFlowIndicator類。
具體代碼依然見源碼;
3.接下來就在布局文件中開始使用了
<framelayout android:id="@+id/framelayout" android:layout_height="300dip" android:layout_width="fill_parent" android:orientation="vertical">
</framelayout>代碼中有個app:activeType,app:radius 這樣的東西,可能新手不是很明白到底是個shenmegui,解釋一下這是自定義屬性。
使用自定義屬性首先要記得把這個屬性相應的命名空間給加在布局文件的開頭,否則無法編譯。
xmlns:app=」http://schemas.android.com/apk/res-auto」
這些屬性都對應在attrs.xml文件中可以找到。
4.然後就可以在Activity中調用了,具體的代碼是:
/**
* @Description:顯示廣告條的主頁
* @author http://blog.csdn.net/finddreams
*/
public class MainActivity extends Activity {
private ViewFlow mViewFlow;
private CircleFlowIndicator mFlowIndicator;
private ArrayList imageUrlList = new ArrayList();
ArrayList linkUrlArray= new ArrayList();
ArrayList titleList= new ArrayList();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
imageUrlList.add(https://gss0..com/9vo3dSag_xI4khGko9WTAnF6hhy/image/pic/item/.jpg);
imageUrlList.add(https://gss0..com/-fo3dSag_xI4khGko9WTAnF6hhy/image/pic/item/.jpg);
imageUrlList.add(https://gss0..com/-Po3dSag_xI4khGko9WTAnF6hhy/image/pic/item/.jpg);
linkUrlArray.add(http://blog.csdn.net/finddreams/article/details/44301359);
linkUrlArray.add(http://blog.csdn.net/finddreams/article/details/43486527);
linkUrlArray.add(http://blog.csdn.net/finddreams/article/details/43194799);
titleList.add(Android開發面試經——);
titleList.add(Android控制項GridView之仿支付寶錢包首頁帶有分割線的GridView九宮格的完美實現);
titleList.add(Android動畫之仿美團載入數據等待時,小人奔跑進度動畫對話框 );
initBanner(imageUrlList);
}
private void initView() {
mViewFlow = (ViewFlow) findViewById(R.id.viewflow);
mFlowIndicator = (CircleFlowIndicator) findViewById(R.id.viewflowindic);
}
private void initBanner(ArrayList imageUrlList) {
mViewFlow.setAdapter(new ImagePagerAdapter(this, imageUrlList,
linkUrlArray, titleList).setInfiniteLoop(true));
mViewFlow.setmSideBuffer(imageUrlList.size()); // 實際圖片張數,
// ImageAdapter實際圖片張數為3
mViewFlow.setFlowIndicator(mFlowIndicator);
mViewFlow.setTimeSpan(4500);
mViewFlow.setSelection(imageUrlList.size() * 1000); // 設置初始位置
mViewFlow.startAutoFlowTimer(); // 啟動自動播放
}
}
5.有一個很關鍵的就是ImagePagerAdapter這個適配器,因為載入網路圖片是在這個類里實現的,還有廣告條的點擊,進入一個Web界面的實現。在這里載入網路圖片使用了一個很火的開源項目,UniversalImageLoader(非同步載入網路圖片) 。
ImagePagerAdapter.class 類:
/**
* @Description: 圖片適配器
* @author http://blog.csdn.net/finddreams
*/
public class ImagePagerAdapter extends BaseAdapter {
private Context context;
private List imageIdList;
private List linkUrlArray;
private List urlTitlesList;
private int size;
private boolean isInfiniteLoop;
private ImageLoader imageLoader;
private DisplayImageOptions options;
public ImagePagerAdapter(Context context, List imageIdList,
List urllist, List urlTitlesList) {
this.context = context;
this.imageIdList = imageIdList;
if (imageIdList != null) {
this.size = imageIdList.size();
}
this.linkUrlArray = urllist;
this.urlTitlesList = urlTitlesList;
isInfiniteLoop = false;
// 初始化imageLoader 否則會報錯
imageLoader = ImageLoader.getInstance();
imageLoader.init(ImageLoaderConfiguration.createDefault(context));
options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.ic_launcher) // 設置圖片下載期間顯示的圖片
.showImageForEmptyUri(R.drawable.meinv) // 設置圖片Uri為空或是錯誤的時候顯示的圖片
.showImageOnFail(R.drawable.meinv) // 設置圖片載入或解碼過程中發生錯誤顯示的圖片
.cacheInMemory(true) // 設置下載的圖片是否緩存在內存中
.cacheOnDisc(true) // 設置下載的圖片是否緩存在SD卡中
.build();
}
@Override
public int getCount() {
// Infinite loop
return isInfiniteLoop ? Integer.MAX_VALUE : imageIdList.size();
}
/**
* get really position
*
* @param position
* @return
*/
private int getPosition(int position) {
return isInfiniteLoop ? position % size : position;
}
@Override
public View getView(final int position, View view, ViewGroup container) {
final ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
view = holder.imageView = new ImageView(context);
holder.imageView
.setLayoutParams(new ViewGroup.LayoutParams(-1, -1));
holder.imageView.setScaleType(ImageView.ScaleType.FIT_XY);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
imageLoader.displayImage(
(String) this.imageIdList.get(getPosition(position)),
holder.imageView, options);
holder.imageView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
String url = linkUrlArray.get(ImagePagerAdapter.this
.getPosition(position));
String title = urlTitlesList.get(ImagePagerAdapter.this
.getPosition(position));
/*
* if (TextUtils.isEmpty(url)) {
* holder.imageView.setEnabled(false); return; }
*/
Bundle bundle = new Bundle();
bundle.putString(url, url);
bundle.putString(title, title);
Intent intent = new Intent(context, BaseWebActivity.class);
intent.putExtras(bundle);
context.startActivity(intent);
Toast.makeText(context, 點擊了第 + getPosition(position) ,
0).show();
}
});
return view;
}
private static class ViewHolder {
ImageView imageView;
}
/**
* @return the isInfiniteLoop
*/
public boolean isInfiniteLoop() {
return isInfiniteLoop;
}
/**
* @param isInfiniteLoop
* the isInfiniteLoop to set
*/
public ImagePagerAdapter setInfiniteLoop(boolean isInfiniteLoop) {
this.isInfiniteLoop = isInfiniteLoop;
return this;
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return arg0;
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return arg0;
}
}
6.點擊進入一個帶進度條的WebView的Activity,載入成功就可以了。
⑶ 如何解決上傳多張圖片時遇到的oom問題
一、OOM問題出現的場景和原因
一個好的app總少不了精美的圖片,所以Android開發中圖片的載入總是避免不了的,而在載入圖片過程中,如果處理不當則會出現OOM的問題。那麼如何徹底解決這個問題呢?本文將具體介紹這方面的知識。
首先我們來總結一下,在載入圖片過程中出現的OOM的場景無非就這么幾種:
1、 載入的圖片過大
2、 一次載入的圖片過多
3、 以上兩種情況兼有
那麼為什麼在以上場景下會出現OOM問題呢?實際上在API文檔中有著明確的說明,出現OMM的主要原因有兩點:
1、移動設備會限制每個app所能夠使用的內存,最小為16M,有的設備分配的會更多,如24、32M、64M等等不一,總之會有限制,不會讓你無限制的使用。
2、在andorid中圖片載入到內存中是以點陣圖的方式存儲的,在android2.3之後默認情況下使用ARGB_8888,這種方式下每個像素要使用4各位元組來存儲。所以載入圖片是會佔用大量的內存。
場景和原因我們都分析完了,下面我們來看看如何解決這些問題。
二、解決大圖載入問題
首先先來解決大圖載入的問題,一般在實際應用中展示圖片時,因屏幕尺寸及布局顯示的原因,我們沒有必要載入原始大圖,只需要按照比例采樣縮放即可。這樣即節省內存又能保證圖片不失真,具體實施步驟如下:
1、在不載入圖片內容的基礎上,去解碼圖片得到圖片的尺寸信息
這里需要用的BitmapFactory的decode系列方法和BitmapFactory.Options。當使用decode系列方法載入圖片時,一定要將Options的inJustDecodeBounds屬性設置為true。
BitmapFactory.Options ptions = new BitmapFactory.Options(); options.inJustDecodeBounds=true; BitmapFactory.decodeFile(path, options);2、根據獲取的圖片的尺寸和要展示在界面的尺寸計算縮放比例。public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height reqHeight || width reqWidth) { if (width height) { inSampleSize = Math.round((float) height / (float) reqHeight); } else { inSampleSize = Math.round((float) width / (float) reqWidth); } } return inSampleSize; }3、根據計算的比例縮放圖片。//計算圖片的縮放比例 options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); options.inJustDecodeBounds = false; Bitmap bitmap= BitmapFactory.decodeFile(path, options);
根據縮放比例,會比原始大圖節省很多內存,效果圖如下:
三、批量載入大圖
下面我們看看如何批量載入大圖,首先第一步還是我們上面所講到的,要根據界面展示圖片控制項的大小來確定圖片的縮放比例。在此我們使用gridview載入本地圖片為例,具體步驟如下:
1、通過系統提供的contentprovider載入外部存儲器中的所有圖片地址private void loadPhotoPaths(){ Cursor cursor= getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, null); while(cursor.moveToNext()){ String path = cursor.getString(cursor.getColumnIndex(MediaColumns.DATA)); paths.add(path); } cursor.close(); }2、自定義adapter,在adapter的getview方法中載入圖片@Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder=null; if(convertView==null){ convertView = LayoutInflater.from(this.mContext).inflate(R.layout.grid_item_layout, null); holder = new ViewHolder(); holder.photo=(ImageView)convertView.findViewById(R.id.photo); convertView.setTag(holder); }else{ holder=(ViewHolder)convertView.getTag(); } final String path = this.paths.get(position); holder.photo.setImageBitmap(imageLoader.getBitmapFromCache(path)); return convertView; }
通過以上關鍵兩個步驟後,我們發現程序運行後,用戶體驗特別差,半天沒有反應,很明顯這是因為我們在主線程中載入大量的圖片,這是不合適的。在這里我們要將圖片的載入工作放到子線程中進行,改造自定義的ImageLoader工具類,為其添加一個線程池對象,用來管理用於下載圖片的子線程。
private ExecutorService executor; private ImageLoader(Context mContxt) { super(); executor = Executors.newFixedThreadPool(3); } //載入圖片的非同步方法,含有回調監聽 public void loadImage(final ImageView view, final String path, final int reqWidth, final int reqHeight, final onBitmapLoadedListener callback){ final Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 1: Bitmap bitmap = (Bitmap)msg.obj; callback.displayImage(view, bitmap); break; default: break; } } }; executor.execute(new Runnable() { @Override public void run() { Bitmap bitmap = loadBitmapInBackground(path, reqWidth, reqHeight); putBitmapInMemey(path, bitmap); Message msg = mHandler.obtainMessage(1); msg.obj = bitmap; mHandler.sendMessage(msg); } }); }
通過改造後用戶體驗明顯好多了,效果圖如下:
雖然效果有所提升,但是在載入過程中還存在兩個比較嚴重的問題:
1、 圖片錯位顯示
2、 當我們滑動速度過快的時候,圖片載入速度過慢
經過分析原因不難找出,主要是因為我們時候holder緩存了grid的item進行重用和線程池中的載入任務過多所造成的,只需要對程序稍作修改,具體如下:
Adapter中:
holder.photo.setImageResource(R.drawable.ic_launcher); holder.photo.setTag(path); imageLoader.loadImage(holder.photo, path, DensityUtil.dip2px(80), DensityUtil.dip2px(80), new onBitmapLoadedListener() { @Override public void displayImage(ImageView view, Bitmap bitmap) { String imagePath= view.getTag().toString(); if(imagePath.equals(path)){ view.setImageBitmap(bitmap); } } });
ImageLoader中:
executor.execute(new Runnable() { @Override public void run() { String key = view.getTag().toString(); if (key.equals(path)) { Bitmap bitmap = loadBitmapInBackground(path, reqWidth, reqHeight); putBitmapInMemey(path, bitmap); Message msg = mHandler.obtainMessage(1); msg.obj = bitmap; mHandler.sendMessage(msg); } } });
為了獲得更好的用戶體驗,我們還可以繼續優化,即對圖片進行緩存,緩存我們可以分為兩個部分內存緩存磁碟緩存,本文例子載入的是本地圖片所有隻進行了內存緩存。對ImageLoader對象繼續修改,添加LruCache對象用於緩存圖片。
private ImageLoader(Context mContxt) { super(); executor = Executors.newFixedThreadPool(3); //將應用的八分之一作為圖片緩存 ActivityManager am=(ActivityManager)mContxt.getSystemService(Context.ACTIVITY_SERVICE); int maxSize = am.getMemoryClass()*1024*1024/8; mCache = new LruCachestring, bitmap=""(maxSize){ @Override protected int sizeOf(String key, Bitmap value) { return value.getRowBytes()*value.getHeight(); } }; } //存圖片到緩存 public void putBitmapInMemey(String path,Bitmap bitmap){ if(path==null) return; if(bitmap==null) return; if(getBitmapFromCache(path)==null){ this.mCache.put(path, bitmap); } } public Bitmap getBitmapFromCache(String path){ return mCache.get(path); }/string,
在loadImage方法中非同步載入圖片前先從內存中取,具體代碼請下載案例。
四、總結
總結一下解決載入圖片出現OOM的問題主要有以下方法:
1、 不要載入原始大圖,根據顯示控制項進行比例縮放後載入其縮略圖。
2、 不要在主線程中載入圖片,主要在listview和gridview中使用非同步載入圖片是要注意處理圖片錯位和無用線程的問題。
3、 使用緩存,根據實際情況確定是否使用雙緩存和緩存大小。
小夥伴們看懂了嘛?想要自己測試的,可以點擊下載工程運行測試哦!
⑷ android Gridview如何控制滑動速度或滑動距離
寫個程序就可以了,具體如下:
1,定義一個類繼承GridView,如下:
public class SourcePanel extends GridView {
public SourcePanel(Context context) {
super(context);
}
public SourcePanel(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SourcePanel(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
}
注意:構造方法要將GridView中的三種構造全部寫上,否則很可能出現解析xml文件異常的錯誤。
2,在該類中重寫dispatchTouchEvent()方法,如下:
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_MOVE) {
return true; //禁止GridView滑動
}
return super.dispatchTouchEvent(ev);
}
3,在布局文件(xml)中定義該控制項時寫全包名,如下(屬性跟GridView控制項屬性一樣,按需求自加):
<com.kz.steerwheel.view.SourcePanel
android:id="@+id/sourcePanel"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
⑸ android中GridView默認是從左往右填寫數據的,一行滿了轉至下行, 我如何實現從上往下填寫數據呢
事件裡面設置,內容改變則自動重置輸入起點位置。
⑹ Android載入更多數據重復顯示的問題該怎麼解決
先開線程下載圖片。等圖片下載完成以後,通過SendMessage的方式通知主線程的Handler更新GridView。