安卓仿QQ空间实现(含图片的动态编辑、发表、点赞、评论)
之前做项目的时候需要用到仿空间动态的功能,在此做一下记录,简单介绍一下listview自定义适配器以及各相关功能实现方法。
一、效果图
这里添加了两条初始动态,其他都是现编现发的。头像这里后面使用了圆形图片控件。
动态评论以及点赞功能实现⬆
动态编辑与发表功能⬆(这个照片是我摸黑拍的,显示并没有问题,并且因为时间比较长降低了gif的图片质量)
二、功能需求
1、仿空间动态界面
2、评论与点赞。
3、发表动态(图片+文字)。
三、 功能实现(主要代码)
1、首先定义一个实体类Dynamic,作为ListView的适配类型。
public class Dynamic {private int iv_head,imagev1;private String tv_name;private String tv_time;private String tv_content;private String ll_comment;private String ivfilepath1;private String ivfilepath2;private String ivfilepath3;public String getTv_dolike() {return tv_dolike;}public void setTv_dolike(String tv_dolike) {this.tv_dolike = tv_dolike;}private String tv_dolike;public void setTv_time(String tv_time) {this.tv_time = tv_time;}public int getImagev1() {return imagev1;}public Dynamic(int iv_head, String tv_name, String tv_content, String ivfilepath1, String ivfilepath2, String ivfilepath3, String tv_time, int imagev1) {this.iv_head = iv_head;this.ivfilepath1=ivfilepath1;this.ivfilepath2=ivfilepath2;this.ivfilepath3=ivfilepath3;this.imagev1=imagev1;this.tv_name = tv_name;this.tv_time = tv_time;this.tv_content = tv_content;}public int getIv_head() {return iv_head;}public String getIvfilepath1() {return ivfilepath1;}public String getIvfilepath2() {return ivfilepath2;}public String getIvfilepath3() {return ivfilepath3;}public String getTv_name() {return tv_name;}public String getTv_time() {return tv_time;}public String getTv_content() {return tv_content;}public String getLl_comment() {return ll_comment;}
}
2、自定义适配器DynamicAdapter,我这里使用的适配器继承自ArrayAdapter,适配器作为后端数据与前端界面交互的桥梁是十分重要的,也是实现定制ListView的关键。
//设置点赞事件,点赞图标变化viewHolder.iv_like.setOnClickListener (new OnClickListener () {@Overridepublic void onClick(View view) {if (!islike) {viewHolder.tv_dolike.setText (username+"觉得很赞");viewHolder.iv_like.setImageResource (R.mipmap.like);Toast.makeText (getContext (), "点赞成功", Toast.LENGTH_SHORT).show ();islike = true;} else {viewHolder.tv_dolike.setText ("");viewHolder.iv_like.setImageResource (R.mipmap.nolike);Toast.makeText (getContext (), "取消点赞", Toast.LENGTH_SHORT).show ();islike = false;}}});//给每一条动态设置内容viewHolder.iv_head.setImageResource (dynamic.getIv_head ());viewHolder.tv_name.setText (dynamic.getTv_name ());viewHolder.tv_content.setText (dynamic.getTv_content ());viewHolder.tv_time.setText (dynamic.getTv_time ());Bitmap bitmap1 = BitmapFactory.decodeFile (dynamic.getIvfilepath1 ());viewHolder.iv_content1.setImageBitmap (bitmap1);Bitmap bitmap2 = BitmapFactory.decodeFile (dynamic.getIvfilepath2 ());viewHolder.iv_content2.setImageBitmap (bitmap2);Bitmap bitmap3 = BitmapFactory.decodeFile (dynamic.getIvfilepath3 ());viewHolder.iv_content3.setImageBitmap (bitmap3);if(dynamic.getImagev1 ()!=0){viewHolder.iv_content1.setImageResource (dynamic.getImagev1 ());}//点击评论图标获取edittext焦点viewHolder.Iv_comment.setOnClickListener (new OnClickListener () {@Overridepublic void onClick(View view) {Log.e ("onClick: ", "获取焦点");if (viewHolder.et_comment.isFocused ()) {} else {viewHolder.et_comment.requestFocus ();viewHolder.et_comment.setFocusableInTouchMode (true);InputMethodManager inputManager =(InputMethodManager) viewHolder.et_comment.getContext ().getSystemService (Context.INPUT_METHOD_SERVICE);inputManager.showSoftInput (viewHolder.et_comment, 0);}}});//评论监听viewHolder.et_comment.setOnTouchListener (new View.OnTouchListener () {@Overridepublic boolean onTouch(View view, MotionEvent motionEvent) {Log.e ("onTouch: ", "发表");Drawable drawable = viewHolder.et_comment.getCompoundDrawables ()[2];//排除非按压图标事件if (motionEvent.getAction () != MotionEvent.ACTION_UP) {return false;}if (motionEvent.getX () > viewHolder.et_comment.getWidth () - drawable.getIntrinsicWidth () - viewHolder.et_comment.getPaddingRight ()) {//取出评论String commentStr = viewHolder.et_comment.getText ().toString ().trim ();if (TextUtils.isEmpty (commentStr)) {Toast.makeText (getContext (), "评论内容不能为空", Toast.LENGTH_SHORT).show ();} else {addView (commentStr, viewHolder.ll_comment);viewHolder.et_comment.setText ("");Toast.makeText (getContext (), "发表成功", Toast.LENGTH_SHORT).show ();}}return false;}});return view;}//动态添加textview实现评论private void addView(String string, LinearLayout linearLayout) {Log.e ("addView: ", "添加评论");TextView textView = new TextView (getContext ());textView.setText (username+": "+string);textView.setTextSize (15);linearLayout.addView (textView);LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) textView.getLayoutParams ();layoutParams.setMargins (0, 0, 0, 20);textView.setLayoutParams (layoutParams);}
①ListView效率优化
每次Listview的子项滑动到屏幕内时会自动调用getView()方法,重复加载布局及获得控件实例会导致ListView的运行效率降低,这里用到了convertView参数将之前加载好的布局缓存,并且自定义了内部ViewHodler类用来缓存控件实例,进行ListView运行效率的优化。
②动态评论功能的实现
首先实例化一个TextView对象,设置好textView的内容与样式,然后添加进布局容器,通过LayoutParams设置textView的布局参数。
③适配器的构造函数
用于在Activity中实例化自定义适配器对象,并且这里构造函数中我取得了listview每个子项目的布局文件,对它进行操作。
3、下面是Activity代码,这里有两个界面,空间动态主界面MainActivity和编辑动态界面WriteActivity。
① WriteActivity
//发表动态buttonPublish.setOnClickListener (new View.OnClickListener () {@Overridepublic void onClick(View view) {//取得数据String stringArticle = editTextArticle.getText ().toString ().trim ();Date date=new Date ();SimpleDateFormat simpleDateFormat=new SimpleDateFormat ("MM-dd HH:mm");stringCurrenttime=simpleDateFormat.format (date);//创建传递数据的intent对象Intent intent1 = new Intent ();//存放数据intent1.putExtra ("editArticle", stringArticle);intent1.putExtra ("photoPath1",imagename1);intent1.putExtra ("photoPath2",imagename2);intent1.putExtra ("photoPath3",imagename3);intent1.putExtra ("stringCurrenttime",stringCurrenttime);setResult (RESULT_OK, intent1);finish ();}});//初始化发表按钮状态buttonPublish.setPressed (true);buttonPublish.setClickable (false);//设置取消按钮buttonCancle.setOnClickListener (new View.OnClickListener () {@Overridepublic void onClick(View view) {buttonCancle.setVisibility (View.INVISIBLE);finish ();}});//文本监听editTextArticle.addTextChangedListener (new TextWatcher () {@Overridepublic void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {Log.e ("beforeTextChanged: ", "初试结果");}@Overridepublic void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {Log.e ("onTextChanged: ", "进行结果");}@Overridepublic void afterTextChanged(Editable editable) {Log.e ("afterTextChanged: ", "最终结果");if (editable.toString ().equals ("")&&imageView2.getDrawable ()==null) {buttonPublish.setPressed (true);buttonPublish.setClickable (false);} else {buttonPublish.setPressed (false);buttonPublish.setClickable (true);}}});
}//点击拍摄
@Override
public void onClick(View view) {Intent intentPhoto = new Intent (MediaStore.ACTION_IMAGE_CAPTURE);switch (view.getId ()) {case R.id.Iv_image1:if (isclickable1) {Log.e ("onClick: ", "拍照");startActivityForResult (intentPhoto, 100);} else {}break;case R.id.Iv_image2:if (isclickable2) {startActivityForResult (intentPhoto, 99);} else {}break;case R.id.Iv_image3:if (isclickable3) {startActivityForResult (intentPhoto, 98);} else {}break;}
}//取出照片并显示
protected void onActivityResult(int a, int b, Intent c) {super.onActivityResult (a, b, c);ImageView imageViewPhoto1, imageViewPhoto2, imageViewPhoto3;imageViewPhoto1 = findViewById (R.id.Iv_image1);imageViewPhoto2 = findViewById (R.id.Iv_image2);imageViewPhoto3 = findViewById (R.id.Iv_image3);if (b == Activity.RESULT_OK) {if (a == 100) {//取出图片Bundle bd = c.getExtras ();bitmap = (Bitmap) bd.get ("data");//获取当前时间得到路径Date date=new Date ();SimpleDateFormat simpleDateFormat=new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");stringDate1=simpleDateFormat.format (date);imagename1="/"+stringDate1+".jpg";Bitmap copyBitmap=createBitmap(bitmap,imagename1);//显示拍摄照片imageViewPhoto1.setScaleType (ImageView.ScaleType.CENTER_CROP);imageViewPhoto1.setImageBitmap (copyBitmap);//显示拍摄按钮imageViewPhoto2.setVisibility (View.VISIBLE);imageViewPhoto2.setImageResource (R.drawable.photoscale);buttonPublish.setClickable (true);buttonPublish.setPressed (false);isclickable1 = false;}if (a == 99) {Bundle bd = c.getExtras ();bitmap = (Bitmap) bd.get ("data");//获取当前时间得到路径Date date=new Date ();SimpleDateFormat simpleDateFormat=new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");stringDate2=simpleDateFormat.format (date);imagename2="/"+stringDate2+".jpg";Bitmap copyBitmap=createBitmap(bitmap,imagename2);//显示拍摄照片imageViewPhoto2.setScaleType (ImageView.ScaleType.CENTER_CROP);imageViewPhoto2.setImageBitmap (copyBitmap); //显示拍摄按钮imageViewPhoto3.setVisibility (View.VISIBLE);imageViewPhoto3.setImageResource (R.drawable.photoscale);isclickable2 = false;}if (a == 98) {Bundle bd = c.getExtras ();bitmap = (Bitmap) bd.get ("data");//获取当前时间得到路径Date date=new Date ();SimpleDateFormat simpleDateFormat=new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");stringDate3=simpleDateFormat.format (date);imagename3="/"+stringDate3+".jpg";Bitmap copyBitmap=createBitmap(bitmap,imagename3);//显示拍摄照片imageViewPhoto3.setScaleType (ImageView.ScaleType.CENTER_CROP);imageViewPhoto3.setImageBitmap (copyBitmap);isclickable3 = false;}}else {Toast.makeText (this, "没有拍摄照片", Toast.LENGTH_SHORT).show ();}}private Bitmap createBitmap(Bitmap bitmap,String photoname){//剪裁图片int W=bitmap.getWidth ();int H=bitmap.getHeight ();Bitmap newBitmap;if (W>H){newBitmap=bitmap.createBitmap (bitmap,(W-H)/2,0,H,H);}else {newBitmap=bitmap.createBitmap (bitmap,0,(H-W)/2,W,W);}//将照片缓存至本地File fileimage;try {fileimage=new File (getCacheDir ()+photoname);if(!fileimage.exists ()){fileimage.getParentFile ().mkdirs ();fileimage.createNewFile ();}FileOutputStream fos=new FileOutputStream (fileimage);newBitmap.compress (Bitmap.CompressFormat.JPEG,100,fos);fos.flush ();fos.close ();} catch (IOException e) {e.printStackTrace ();}return newBitmap;
}
这里利用了系统时间以得到不同的照片命名并存储至本地。此外这里有关文件的操作后续要深入了解一下。
②MainActivity
//新增动态显示数据
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){super.onActivityResult (requestCode,resultCode,data);switch(requestCode){case 1:if (resultCode==RESULT_OK){String stringArticle=data.getStringExtra ("editArticle");**//得到图片路径String imagepath1=get**CacheDir ()+data.getStringExtra ("photoPath1");String imagepath2=getCacheDir ()+data.getStringExtra ("photoPath2");String imagepath3=getCacheDir ()+data.getStringExtra ("photoPath3");// 获得发表时间String stringCurrenttime=data.getStringExtra ("stringCurrenttime"); Dynamic C=new Dynamic (R.drawable.myhead,"admin",stringArticle,imagepath1,imagepath2,imagepath3,stringCurrenttime,0);dynamicList.add(0,C);listView.setAdapter (adapter); Toast.makeText (getApplicationContext (),"发表成功",Toast.LENGTH_SHORT).show ();}break;}
这里要注意的是,listView中的数据刷新后要重新setAdapter,否则界面动态数据无法刷新。
四、最后
我写这些博客主要是为了加深自己的理解,也供后续回顾,有什么建议与想法大家都可以在下方评论或者私信我,互相交流共同进步。
安卓仿QQ空间实现(含图片的动态编辑、发表、点赞、评论)相关推荐
- php 朋友圈留言,php实例-PHP仿qq空间或朋友圈发布动态、评论动态、回复评论、删除动态或评论的功能(上)...
我们大部分人都发过动态,想必都知道发动态.回复评论.删除动态的整个过程,那么这个功能是如何实现的呢?下面小编给大家带来了实例代码,对PHP仿qq空间或朋友圈发布动态.评论动态.回复评论.删除动态或评论 ...
- php mysql仿微信朋友圈评论表设计_PHP仿qq空间或朋友圈发布动态、评论动态、回复评论、删除动态或评论的功能(上)...
我们大部分人都发过动态,想必都知道发动态.回复评论.删除动态的整个过程,那么作为初学者,要模仿这些功能有点复杂的,最起码表的关系得弄清楚~~ 先把思路理一下: (1)用户登录,用session读取当前 ...
- html5仿qq空间,JS实现的仿QQ空间图片弹出效果代码
本文实例讲述了JS实现的仿QQ空间图片弹出效果代码.分享给大家供大家参考,具体如下: function imageShow(which_click) { var image_path = which_ ...
- 仿QQ空间图片放缩查看
仿QQ空间图片放缩查看 仿QQ空间图片放缩查看,点击图片从原位置放大到全屏,后退从全屏缩小到原位置,效果非常好. 下载地址:http://www.devstore.cn/code/info/830.h ...
- android写qq动态界面,Android_Android仿QQ空间主页面的实现,今天模仿安卓QQ空间,效果如 - phpStudy...
Android仿QQ空间主页面的实现 今天模仿安卓QQ空间,效果如下: 打开程序的启动画面和导航页面我就不做了,大家可以模仿微信的那个做一下,很简单.这次主要做一下主页面的实现,下面是主页面的布局: ...
- 仿QQ空间,百思不得姐下拉刷新图片放大
1.概述 实习生进阶到项目部分会带他们做一个百思不得姐项目,那么个人主页就有类似于QQ空间下拉图片放大的效果,趁着现在还闲就实现一下效果: 2.实现 1. 效果分析 ScrollView和ListVi ...
- 【Android UI设计与开发】第09期:底部菜单栏(四)Fragment+PopupWindow仿QQ空间最新版底部菜单栏
转载请注明出处:http://blog.csdn.net/yangyu20121224/article/details/9023451 在今天的这篇文章当中,我依然会以实战加理论结合 ...
- java仿qq空间音乐播放_完美实现仿QQ空间评论回复特效
评论回复是个很常见的东西,但是各大网站实现的方式却不尽相同.大体上有两种方式 1. 像优酷这种最常见,在输入框中@要回复的人,这种方式下,用www.cppcns.com户可以修改@. 新浪微博则是在这 ...
- java 仿qq空间_仿QQ空间和微信朋友圈,高解耦高复用高灵活
先看看效果: 用极少的代码实现了 动态详情 及 二级评论 的 数据获取与处理 和 UI显示与交互,并且高解耦.高复用.高灵活. 动态列表界面MomentListFragment支持 下拉刷新与上拉加载 ...
最新文章
- BAT都在使用的开源接口管理平台,你用了吗?
- ML之RS:基于用户的CF+LFM实现的推荐系统(基于相关度较高的用户实现电影推荐)
- ASP.NET服务器应用程序不可用
- https和http的主要区别
- 数据下载工作笔记三:脚本
- 调整样式_2019年4月1日起,内河船船员适任证书样式调整成这样啦~
- 实战例子_Pytorch官方力荐新书《Pytorch深度学习实战指南》pdf及代码分享
- RestTemplate使用笔记
- 读写锁原理 java_java多线程-读写锁原理
- Android集成三方浏览器之X5内核,从入门到精通
- moodle平台安装及环境配置(包括安装过程详细截图)
- RGB、HSL、Hex网页色彩码,看完这篇全懂了
- Altium Designer 18中查找元器件的四种方法
- 当代博物馆中的3DGIS虚拟现实搭建
- h5混合开发框架初识
- dubbo暴露出HTTP服务
- 移动开发程序员的悲哀是什么?
- List集合转字符串,逗号隔开
- OCR目标识别(车辆VIN码识别效果)
- EXCEL 字符替换为换行符