安卓仿QQ空间实现(含图片的动态编辑、发表、点赞、评论) 您所在的位置:网站首页 qq空间单图背景 安卓仿QQ空间实现(含图片的动态编辑、发表、点赞、评论)

安卓仿QQ空间实现(含图片的动态编辑、发表、点赞、评论)

2023-10-31 10:47| 来源: 网络整理| 查看: 265

目录 之前做项目的时候需要用到仿空间动态的功能,在此做一下记录,简单介绍一下listview自定义适配器以及各相关功能实现方法。一、效果图二、功能需求三、 功能实现(主要代码)四、最后 2023更新

之前做项目的时候需要用到仿空间动态的功能,在此做一下记录,简单介绍一下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 () { @Override public 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 () { @Override public 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 () { @Override public 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 () { @Override public 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 () { @Override public void onClick(View view) { buttonCancle.setVisibility (View.INVISIBLE); finish (); } }); //文本监听 editTextArticle.addTextChangedListener (new TextWatcher () { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { Log.e ("beforeTextChanged: ", "初试结果"); } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { Log.e ("onTextChanged: ", "进行结果"); } @Override public 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,否则界面动态数据无法刷新。

四、最后

我写这些博客主要是为了加深自己的理解,也供后续回顾,有什么建议与想法大家都可以在下方评论或者私信我,互相交流共同进步。

2023更新

源码现已上传至csdn,点击下载***



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有