作为一个菜鸟突然想了解一下气泡弹窗,于是查找资料就写了一个简单的弹窗PopupWindow,
个人感觉符合菜鸟的水平;
public class MyLinear extends LinearLayout {
private Paint paint;
//view的宽高
int widthSize;
int heightSize;
public MyLinear(Context context) {
super(context);
init();
}
public MyLinear(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public MyLinear(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
paint = new Paint();
paint.setAntiAlias(true);//设置抗锯齿
//设置是否抖动,如果不设置感觉就会有一些僵硬的线条,如果设置图像就会看的更柔和一些,
paint.setDither(true);
paint.setStyle(Paint.Style.FILL_AND_STROKE);//填充内部和描边
paint.setColor(getResources().getColor(R.color.bg));
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int specMode = MeasureSpec.getMode(widthMeasureSpec);
int specSize = MeasureSpec.getSize(widthMeasureSpec);
int specModeh = MeasureSpec.getMode(heightMeasureSpec);
int specSizeh = MeasureSpec.getSize(heightMeasureSpec);
if (specMode == MeasureSpec.AT_MOST) {//设置为wrap_content
widthSize =300;
} else if (specMode == MeasureSpec.EXACTLY) {//相当于我们设置为match_parent或者为一个具体的值
widthSize = specSize;
}
if (specModeh == MeasureSpec.AT_MOST) {
heightSize =400;
} else if (specModeh == MeasureSpec.EXACTLY) {//相当于我们设置为match_parent或者为一个具体的值
heightSize = specSizeh;
}
/*widthSize = specSize;
heightSize = specSizeh;*/
setMeasuredDimension(widthSize, heightSize);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画矩形
RectF rectF = new RectF(0,20,widthSize,heightSize);
canvas.drawRoundRect(rectF,10,10,paint);
//画三角形(这里是基于path路径的绘制)
Path path = new Path();
Log.d("width", "onDraw: "+widthSize);
Log.d("width", "onDrawh: "+heightSize);
path.moveTo(widthSize-25, 0);
path.lineTo(widthSize-10, 20);
path.lineTo(widthSize-40, 20);
path.close();
canvas.drawPath(path, paint);
canvas.save();
}
}
//listview是为了好加载选项
至于弹窗的大小与位置,注意上面的onMesure()方法
package com.example.dell.mypopupwindows.adapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.dell.mypopupwindows.Datas;
import com.example.dell.mypopupwindows.R;
import java.util.ArrayList;
public class ItemAdapter extends BaseAdapter {
private ArrayList arrayList;
public ItemAdapter(ArrayList arrayList){
this.arrayList = arrayList;
}
@Override
public int getCount() {
return arrayList.size();
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
View view = null;
ViewHolder viewHolder = new ViewHolder();
if (convertView == null) {
view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_item,viewGroup,false);
viewHolder.tv1 = view.findViewById(R.id.tv);
viewHolder.img1 = view.findViewById(R.id.img);
view.setTag(viewHolder);
} else {
view = convertView;
viewHolder = (ViewHolder) view.getTag();
}
viewHolder.tv1.setText(arrayList.get(i).getTv());
viewHolder.img1.setImageResource(arrayList.get(i).getImg());
return view;
}
private class ViewHolder {
TextView tv1;
ImageView img1;
}
}
public class MyPopup extends PopupWindow {
private Context context;
private View view;
private ListView listView;
private ArrayList arrayList;
public MyPopup(Context context,View parent) {
super(context);
this.context = context;
//设置弹窗大小
setWidth(300);
setHeight(400);
//设置可以获得焦点
setFocusable(true);
//设置弹窗内可点击
setTouchable(true);
//设置弹窗外可点击
setOutsideTouchable(true);
//背景
setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
or// setBackgroundDrawable(new BitmapDrawable());
//加载弹窗布局
view = LayoutInflater.from(context).inflate(R.layout.popu_menu,null);
setContentView(view);
//建立弹窗内容
initData();
//显示弹窗, 第一个参数是PopupWindow的锚点,第二和第三个参数分别是PopupWindow相对锚点的x、y偏移
showAsDropDown(parent , 0, 0);
// showAtLocation(parent, Gravity.BOTTOM, 0, 0);
}
private void initData() {
listView= view.findViewById(R.id.listview1);
arrayList = new ArrayList<>();
arrayList.add(new Datas("弹窗",R.mipmap.ic_launcher));
arrayList.add(new Datas("弹窗2",R.mipmap.ic_launcher));
arrayList.add(new Datas("弹窗3",R.mipmap.ic_launcher));
listView.setAdapter(new ItemAdapter(arrayList));
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> adapterView, View view, int i, long l) {
///Toast.makeText(context,"点击:"+arrayList.get(i).getTv(),Toast.LENGTH_SHORT).show();
Intent intent = new Intent(context, SecondActivitv.class);
context.startActivity(intent);
}
});
}
}
注意:如果不设置PopupWindow的背景,有些版本就会出现一个问题:无论是点击外部区域还是Back键都无法dismiss弹框
setOutsideTouchable(true);
setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
public class MainActivity extends AppCompatActivity {
private ListView listView;
private ArrayList arrayList;
private TextView mainTv;
private LinearLayout linearLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainTv = findViewById(R.id.maintv);
mainTv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new MyPopup(MainActivity.this,view);//在需要的地方加载
}
});
}
}
如图:点击helloworld发生变化
参考链接 :1.https://blog.csdn.net/caicdd007/article/details/51933656
2.https://www.cnblogs.com/jzyhywxz/p/7039503.html