之前做项目的时候需要用到仿空间动态的功能,在此做一下记录,简单介绍一下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空间实现(含图片的动态编辑、发表、点赞、评论)相关推荐

  1. php 朋友圈留言,php实例-PHP仿qq空间或朋友圈发布动态、评论动态、回复评论、删除动态或评论的功能(上)...

    我们大部分人都发过动态,想必都知道发动态.回复评论.删除动态的整个过程,那么这个功能是如何实现的呢?下面小编给大家带来了实例代码,对PHP仿qq空间或朋友圈发布动态.评论动态.回复评论.删除动态或评论 ...

  2. php mysql仿微信朋友圈评论表设计_PHP仿qq空间或朋友圈发布动态、评论动态、回复评论、删除动态或评论的功能(上)...

    我们大部分人都发过动态,想必都知道发动态.回复评论.删除动态的整个过程,那么作为初学者,要模仿这些功能有点复杂的,最起码表的关系得弄清楚~~ 先把思路理一下: (1)用户登录,用session读取当前 ...

  3. html5仿qq空间,JS实现的仿QQ空间图片弹出效果代码

    本文实例讲述了JS实现的仿QQ空间图片弹出效果代码.分享给大家供大家参考,具体如下: function imageShow(which_click) { var image_path = which_ ...

  4. 仿QQ空间图片放缩查看

    仿QQ空间图片放缩查看 仿QQ空间图片放缩查看,点击图片从原位置放大到全屏,后退从全屏缩小到原位置,效果非常好. 下载地址:http://www.devstore.cn/code/info/830.h ...

  5. android写qq动态界面,Android_Android仿QQ空间主页面的实现,今天模仿安卓QQ空间,效果如 - phpStudy...

    Android仿QQ空间主页面的实现 今天模仿安卓QQ空间,效果如下: 打开程序的启动画面和导航页面我就不做了,大家可以模仿微信的那个做一下,很简单.这次主要做一下主页面的实现,下面是主页面的布局: ...

  6. 仿QQ空间,百思不得姐下拉刷新图片放大

    1.概述 实习生进阶到项目部分会带他们做一个百思不得姐项目,那么个人主页就有类似于QQ空间下拉图片放大的效果,趁着现在还闲就实现一下效果: 2.实现 1. 效果分析 ScrollView和ListVi ...

  7. 【Android UI设计与开发】第09期:底部菜单栏(四)Fragment+PopupWindow仿QQ空间最新版底部菜单栏

    转载请注明出处:http://blog.csdn.net/yangyu20121224/article/details/9023451          在今天的这篇文章当中,我依然会以实战加理论结合 ...

  8. java仿qq空间音乐播放_完美实现仿QQ空间评论回复特效

    评论回复是个很常见的东西,但是各大网站实现的方式却不尽相同.大体上有两种方式 1. 像优酷这种最常见,在输入框中@要回复的人,这种方式下,用www.cppcns.com户可以修改@. 新浪微博则是在这 ...

  9. java 仿qq空间_仿QQ空间和微信朋友圈,高解耦高复用高灵活

    先看看效果: 用极少的代码实现了 动态详情 及 二级评论 的 数据获取与处理 和 UI显示与交互,并且高解耦.高复用.高灵活. 动态列表界面MomentListFragment支持 下拉刷新与上拉加载 ...

最新文章

  1. BAT都在使用的开源接口管理平台,你用了吗?
  2. ML之RS:基于用户的CF+LFM实现的推荐系统(基于相关度较高的用户实现电影推荐)
  3. ASP.NET服务器应用程序不可用
  4. https和http的主要区别
  5. 数据下载工作笔记三:脚本
  6. 调整样式_2019年4月1日起,内河船船员适任证书样式调整成这样啦~
  7. 实战例子_Pytorch官方力荐新书《Pytorch深度学习实战指南》pdf及代码分享
  8. RestTemplate使用笔记
  9. 读写锁原理 java_java多线程-读写锁原理
  10. Android集成三方浏览器之X5内核,从入门到精通
  11. moodle平台安装及环境配置(包括安装过程详细截图)
  12. RGB、HSL、Hex网页色彩码,看完这篇全懂了
  13. Altium Designer 18中查找元器件的四种方法
  14. 当代博物馆中的3DGIS虚拟现实搭建
  15. h5混合开发框架初识
  16. dubbo暴露出HTTP服务
  17. 移动开发程序员的悲哀是什么?
  18. List集合转字符串,逗号隔开
  19. OCR目标识别(车辆VIN码识别效果)
  20. EXCEL 字符替换为换行符

热门文章

  1. 晶振知识小结(晶振电路设计)
  2. vert.x demo启动步骤
  3. 小程序开发实例:指南针(1)
  4. linux awk学习(每日一令之十五)
  5. 华为手机教程 线刷 华为手机救砖 高维禁用UPDATE.APP 解包 刷机教学 教程
  6. 基于xDSL宽带网络测试系统的TL1通信协议设计与实现
  7. AMSS - Advanced Mobile Subscriber Software
  8. 基于前端页面开发课程教学网站的设计与实现
  9. Automake 使用手册
  10. arcgis 实现分屏功能