最近項目在做im即時通訊開發,在删除聊天清單的時候跟删除聊天詳細資訊的時候,産品經理想要跟ios一樣,在目前選中行上方彈出一個删除視窗.于是先從網上找demo,找了一個發現是dialog做的,我感覺沒有必要這麼麻煩,于是我用popupwindow實作了一個,有需要的朋友可以參考一下。
1.效果圖如下(長按清單彈窗,消息詳細資訊長按彈窗)
2.對源碼進行說明。
一條消息實體類,有消息内容跟是否發送這兩個屬性。
public class message {
private string content;// 消息内容
private boolean sended;// 是否發送
public message(){
}
public message(string content,boolean sended){
this.content=content;
this.sended=sended;
public string getcontent() {
return content;
public void setcontent(string content) {
this.content = content;
public boolean issended() {
return sended;
public void setsended(boolean sended) {
this.sended = sended;
}
消息詳細資訊的activity
1).給每條消息設定長按事件,把點選的下标用tag傳進去
2).用popupwindow展示,顯示在目前點選的view下方,然後設定xy的偏移度
* 消息詳細界面
* @author ansen
* @create time 2015-08-04
*/
public class messagedetailactivity extends activity{
private list<message> messages=new arraylist<message>();
private listview listview;
private myadapter madapter;
private popupwindow popupwindow;
private textview tvdelete;
private edittext etinput;
private int longclickposition;
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_private_message_detail_list);
initdata();
listview=(listview) findviewbyid(r.id.list_private_message);
listview.setadapter(madapter=new myadapter());
textview sendmessage=(textview) findviewbyid(r.id.tv_send_message);
sendmessage.setonclicklistener(clicklistener);
etinput=(edittext) findviewbyid(r.id.et_input);
private class myadapter extends baseadapter{
private layoutinflater inflater;
public myadapter(){
inflater=layoutinflater.from(messagedetailactivity.this);
}
@override
public int getcount() {
return messages.size();
public object getitem(int position) {
return messages.get(position);
public long getitemid(int position) {
return position;
public view getview(int position, view convertview, viewgroup parent) {
viewholder holder = null;
if(null==convertview){
holder=new viewholder();
convertview= inflater.inflate(r.layout.item_private_message_chat,parent,false);
holder.tvmessageto=(textview) convertview.findviewbyid(r.id.tv_message_to);
holder.ivmessagetoheadimage=(imageview) convertview.findviewbyid(r.id.iv_message_to_head_image);
holder.tvmessagefrom=(textview) convertview.findviewbyid(r.id.tv_message_from);
holder.ivmessagefromheadimage=(imageview) convertview.findviewbyid(r.id.iv_message_from_head_image);
convertview.settag(holder);
}else{
holder=(viewholder) convertview.gettag();
}
message message=messages.get(position);
if(message.issended()){//發送消息
holder.tvmessageto.setvisibility(view.gone);
holder.ivmessagetoheadimage.setvisibility(view.gone);
holder.tvmessagefrom.setvisibility(view.visible);
holder.tvmessagefrom.settext(message.getcontent());
holder.tvmessagefrom.setonlongclicklistener(longclicklistener);
holder.tvmessagefrom.settag(position);
holder.ivmessagefromheadimage.setvisibility(view.visible);
}else{//接收消息
holder.tvmessagefrom.setvisibility(view.gone);
holder.ivmessagefromheadimage.setvisibility(view.gone);
holder.tvmessageto.setvisibility(view.visible);
holder.tvmessageto.settext(message.getcontent());
holder.tvmessageto.setonlongclicklistener(longclicklistener);
holder.tvmessageto.settag(position);
holder.ivmessagetoheadimage.setvisibility(view.visible);
return convertview;
private class viewholder{
private imageview ivmessagetoheadimage;//接收消息使用者頭像
private textview tvmessageto;//接收消息内容
private imageview ivmessagefromheadimage;//發送消息使用者頭像
private textview tvmessagefrom;//發送消息内容
private onlongclicklistener longclicklistener=new onlongclicklistener() {
public boolean onlongclick(view v) {
longclickposition=(integer) v.gettag();
showdialog(v);
return true;
};
private void showdialog(view view){
if(null==popupwindow){
view popview = layoutinflater.from(this).inflate(r.layout.layout_long_click_dialog, null);
tvdelete=(textview) popview.findviewbyid(r.id.tv_delete);
tvdelete.setonclicklistener(clicklistener);
popupwindow = new popupwindow(popview, layoutparams.wrap_content, layoutparams.wrap_content);
popupwindow.setanimationstyle(r.style.popanimstyle);
popupwindow.setoutsidetouchable(true);
popupwindow.setbackgrounddrawable(new bitmapdrawable());
if (popupwindow.isshowing())
popupwindow.dismiss();
//第一次顯示控件的時候寬高會為0
int deleteheight=tvdelete.getheight()==0?145:tvdelete.getheight();
int deletewidth=tvdelete.getwidth()==0?212:tvdelete.getwidth();
popupwindow.showasdropdown(view,(view.getwidth()-deletewidth)/2,-view.getheight()-deleteheight);
private onclicklistener clicklistener=new onclicklistener() {
public void onclick(view v) {
switch (v.getid()) {
case r.id.tv_delete:
messages.remove(longclickposition);
madapter.notifydatasetchanged();
popupwindow.dismiss();
break;
case r.id.tv_send_message:
string content=etinput.gettext().tostring().trim();
if(!textutils.isempty(content)){
message message=new message(content, true);
messages.add(message);
madapter.notifydatasetchanged();
listview.setselection(madapter.getcount()-1);
}
private void initdata(){
message message=new message("範德薩範德", true);
message message7=new message("範德薩範德fds", true);
message message1=new message("個人提個人鬼地", false);
message message4=new message("接收消息", false);
message message2=new message("吃飯了嘛。。。。吃過了沒有啊。。。。。還沒有吃啊 範德薩範德薩發水電費的說法都是", true);
message message3=new message("吃飯了嘛。。。。吃過了沒有啊。。。。。還沒有吃啊 範德薩範德薩發水電費的說法都是", false);
messages.add(message);
messages.add(message1);
messages.add(message2);
messages.add(message3);
messages.add(message4);
messages.add(message7);
消息詳細清單布局檔案 activity_private_message_detail_list.xml
<?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" >
<listview
android:id="@+id/list_private_message"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/ll_bottom"
android:divider="@null" >
</listview>
<include
android:id="@+id/ll_bottom"
android:layout_height="wrap_content"
android:layout_alignparentbottom="true"
layout="@layout/layout_input_comment" />
</relativelayout>
底部輸入框布局
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<relativelayout
android:layout_width="wrap_content"
android:paddingbottom="7dip"
android:paddingtop="7dip">
<imageview
android:id="@+id/iv_message_to_head_image"
android:layout_alignparentleft="true"
android:layout_marginleft="5dp"
android:layout_marginright="5dp"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@drawable/slide_left_avatar_default"/>
<textview
android:id="@+id/tv_message_to"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/icon_message_to"
android:gravity="center"
android:paddingleft="20dip"
android:textcolor="@color/register_text_color"
android:layout_torightof="@+id/iv_message_to_head_image"
android:layout_marginright="55dp"
android:textsize="16dip"/>
android:id="@+id/tv_message_from"
android:layout_toleftof="@+id/iv_message_from_head_image"
android:background="@drawable/icon_message_from"
android:paddingright="20dip"
android:textcolor="@color/white_normal"
android:layout_marginleft="55dp"
android:text="我已經吃過了"
<!-- -->
android:id="@+id/iv_message_from_head_image"
android:layout_alignparentright="true"
</relativelayout>
</linearlayout>
每一條消息的布局檔案
彈出删除按鈕的布局檔案
<framelayout xmlns:android="http://schemas.android.com/apk/res/android"
<textview
android:id="@+id/tv_delete"
android:background="@drawable/icon_private_message_delete"
android:gravity="center_horizontal"
android:padding="5dp"
android:text="删除"
android:textcolor="#ffffffff" />
</framelayout>
<a target="_blank" href="http://download.csdn.net/detail/lowprofile_coding/8958311">點選連結下載下傳源碼</a>