編輯:關於Android編程
以前剛剛入門的時候,聽別人說Adapter是一個好東西,一時沒法體會……結合最近項目中有個需求,就是在界面顯示已經配對了的設備的圖標並且可以直接在顯示界面做更新操作,包括刪除,移動和組合的效果,並且長按時在所有item的右上角顯示刪除的小圖標,類似於QQ的那種效果。最後利用GridView(項目中我用的是RecycleView)實現了,又正好整個博客系列中沒有細講過GridView這一知識點,為了知識體系的完整,遂有了以下的文章,重點是分享下自己解決這個問題的思想。
GridView與之前我們熟悉的ListView(現在基本已被RecycleView所替代)一樣都是比較常用的多控件布局,他們都是AdapterView的子類,不同的是GridView可以一行顯示多個item,具體顯示多少個item取決於開發者的設置,實現網格布局的首選。與其他AdapterView的原理一樣,可以理解為我們的GridView和ItemView提供了UI框架,而Adapter則是往這個框架裡填充數據,所以每一次GridView的每一條item生成到的時候都會觸發Adpater相關的生命周期方法。
GridView的使用相信那已不是難點了,有些時候常常被困擾在一些看似酷炫高深的效果上,其實很多時候並不是不會也許是對於一些原理性的東西理解不透徹,很多初學者只是停留在會用,只知其然而不知其所以然,所以一以為過來人的身份建議初學者不要只滿足於按照書本或者視頻敲了代碼,至少要懂得一個大致的原理流程,不至於以後需要實現稍微復雜的效果而一臉茫然。說了那麼多,其實一開始看到這個效果,我也不是一下子就想到了方案的,下面就分享下思路歷程,首先想到的是直接自定義View把它自己畫出來,後面和產品一聊,果斷放棄了這個方案,因為用戶配對的設備數量(從服務器傳過來)可能會有很多而且後期還需要實現自由移動,其實我心裡一開始就有了思路的,只是想偷懶不想去做那麼多的邏輯判斷,可最後還是使用了現在的方案。核心思想就是:Adapter是個好東西,動態更新Adapter進而去更新UI。直接不好實現間接也是可以的。最後的效果大概是這樣的(自由移動的代碼被我精簡掉了,而且這個demo是有小bug的,在項目中我已經解決了,主要是為了分享下體會和思想):

<framelayout android:id="@+id/id_img_content" android:layout_height="wrap_content" android:layout_width="wrap_content"> </framelayout>
其實這只是一種方式,作為簡單的demo,我直接是把數據源寫死了,而且為了避免去封裝bean什麼的,我使用的是一個全局變量來標識是否需要顯示刪除小圖標,真正在我的項目中由於要和服務器通信我使用的是把這一個字段一起封裝到Bean中,然後在Adapter裡判斷,在Activity直接去更新Adpter再notifyDataSetChanged,但是核心思路是一樣一樣的。
package crazymo.train.gridviewtraining;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import crazymo.train.gridviewtraining.util.Util;
import static android.widget.AdapterView.OnItemClickListener;
import static android.widget.AdapterView.OnItemLongClickListener;
/**
* Created by CrazyMo on 2016/10/03.
*/
public class MainActivity extends AppCompatActivity {
private boolean isShowDelete = false;
private List names=new ArrayList();
private List imgs=new ArrayList();
private MainAdapter mainAdapter;
//@BindView(R.id.id_grid_main)
private GridView gridView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//ButterKnife.bind(this);
gridView= (GridView) findViewById(R.id.id_grid_main);
init();
mainAdapter=new MainAdapter(MainActivity.this,names,imgs);
gridView.setAdapter(mainAdapter);
gridView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
mainAdapter.setClickItemIndex(position);
Log.d("TAG", "onItemClick: "+position);
}
});
gridView.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView parent, View view, int position, long id) {
if (isShowDelete) {
isShowDelete = false;
} else {
isShowDelete = true;
}
Log.d("TAG","onItemLongClicked");
mainAdapter.setShowDelete(isShowDelete);
mainAdapter.setClickItemIndex(position);
return true;
}
});
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return super.onKeyDown(keyCode, event);
}
@Override
public void onBackPressed() {
if (mainAdapter.getShowDelete() == true) {
mainAdapter.setShowDelete(false);
} else {
finish();
}
}
private void init(){
initImg();
initName();
}
private void initImg() {
imgs.add(R.mipmap.ic_item);
imgs.add(R.mipmap.ic_item1);
imgs.add(R.mipmap.ic_item2);
imgs.add(R.mipmap.ic_item3);
imgs.add(R.mipmap.ic_item4);
imgs.add(R.mipmap.ic_item5);
}
private void initName(){
for(int i=0;i<6;i++) {
names.add("img name"+i);
}
}
class MainAdapter extends BaseAdapter{
private LayoutInflater inflater;
private List names;
private List icons;
private Context context;
private ImageView img;
private View deleteView;
private boolean isShowDelete;//根據這個變量來判斷是否顯示刪除圖標,true是顯示,false是不顯示
private int clickItemIndex=-1;//根據這個變量來辨識選中的current值
public MainAdapter(Context context,List names,List icons) {
inflater=LayoutInflater.from(context);
this.context=context;
this.names=names;
this.icons = icons;
}
protected void setShowDelete(boolean isShowDelete){
this.isShowDelete=isShowDelete;
notifyDataSetChanged();
}
protected boolean getShowDelete(){
return isShowDelete;
}
protected void setClickItemIndex(int postion){
this.clickItemIndex=postion;
}
@Override
public int getCount() {
return icons.size();
}
@Override
public Object getItem(int position) {
return icons.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder=null;
if(convertView==null){
convertView=inflater.inflate(R.layout.girdv_item_mian,null);
viewHolder=new ViewHolder();
viewHolder.name= (TextView) convertView.findViewById(R.id.id_name);
viewHolder.icon= (ImageView) convertView.findViewById(R.id.id_img_src);
viewHolder.dele= (ImageView) convertView.findViewById(R.id.id_imv_dele);
convertView.setTag(viewHolder);
}else{
viewHolder= (ViewHolder) convertView.getTag();
}
viewHolder.name.setText(names.get(position).toString());
viewHolder.icon.setBackgroundResource((Integer) icons.get(position));
viewHolder.icon.setClickable(false);
viewHolder.dele.setVisibility(isShowDelete?View.VISIBLE:View.GONE);
if(viewHolder.dele.getVisibility()==View.VISIBLE) {
if (position == clickItemIndex) {
viewHolder.dele.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("TAG", "onClick: "+clickItemIndex);
Util.removeListEmlement(icons, (Integer) icons.get(clickItemIndex));
Util.removeListEmlement(names, names.get(clickItemIndex).toString());
notifyDataSetChanged();
}
});
}
}
return convertView;
}
}
class ViewHolder{
TextView name;
ImageView icon;
ImageView dele;
}
}
Android SpannableString淺析
引言在應用程序開發過程經常需要對文本進行處理,比如說對一段描述文字的其中一段加入點擊事件,或者對其設置不一樣的前景色,有什麼方法可以實現要求的功能吶?需求樣例比如我們需要
我的Android進階之旅------)Android編譯錯誤java.util.zip.ZipException: duplicate entry的解決方法
今天在Android Studio中把另外一個項目引入當前項目,編譯的時候出現了java.util.zip.ZipException: duplicate entry錯誤
Android天氣預報app改進版
最近總是有人來和我說我以前寫的一個小app無法正常獲取數據~Android簡易版天氣預報app 今天就又運行了下來查找問題,發現或許是接口有限制吧,不能在多台手機使用同個
android開發之自定義AutoCompleteTextView
AutoCompleteTextView,很多人都用過,有些情況下使用Google提供的ArrayAdapter作為適配器就可以完成需求,但是在實際開發中,我們經常需要開