高仿微信新消息提示音功能

最近公司在做一个项目,有一个切换消息提示音的功能,可以切换本应用收到消息的提示音,而不影响系统提示音。我就按照微信的那个样式进行了编程,最终得到想要的效果。

转载请注明出处,谢谢:http://blog.csdn.net/harryweasley/article/details/46408037

怕有些人不知道怎么进入微信的新消息提示音功能,我这里说下操作步骤:

打开微信----我---设置---新消息提醒---新消息提示音。

经过以上的步骤就进入了这样的界面

这个是微信的效果图。

下面是我自己编程的效果图,如下图所示:

可以看到这两效果差别不是很大。

现在开始介绍一下具体实现的步骤。

本功能的最主要的功能是,这也是难点之一:获取到手机系统的提示音,并将它们显示在一个listview里面。

参考如下代码:

		// 获得RingtoneManager对象
		RingtoneManager manager = new RingtoneManager(this);
		// 设置RingtoneManager对象的类型为TYPE_NOTIFICATION,这样只会获取到notification的对应内容
		manager.setType(RingtoneManager.TYPE_NOTIFICATION);
		Cursor cursor = manager.getCursor();
		int num = cursor.getCount();
		Log.i("tag", num + "消息音个数");
		// 存储消息音名字的arrayList
		ArrayList<String> ringtoneList = new ArrayList<String>();
		for (int i = 0; i < num; i++) {
			//获取当前i的铃声信息
			Ringtone ringtone = manager.getRingtone(i);
			//获取当前i的uri,设置notification的自定义铃声要用到
			Uri uri = manager.getRingtoneUri(i);
			//获取到当前铃声的名字
			String title = ringtone.getTitle(this);
			ringtoneList.add(title);

		}

将获取到的消息提示音的名字,加入到arrayList里。

先将主界面的信息贴上来,看一下,我再慢慢解释:

package jz.his.activity;

import java.util.ArrayList;

import jz.his.adapter.RingtoneAdapter;
import jz.his.jzhis.R;
import jz.his.util.SharedPreferenceUtil;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;

public class RingtoneActivity extends Activity {
	ArrayList<String> ringtoneList;
	ListView listView;
	RingtoneManager manager;
	RingtoneAdapter adapter;
	String ringName = "";

	/**
	 * 选择铃声的uri
	 */
	Uri uri = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_ringtone);
		listView = (ListView) findViewById(R.id.ringtone);
		getRingtone();
		// initRingtoneManager();

		// ringtoneList = FunctionActivity.ringtoneList;
		adapter = new RingtoneAdapter(this, ringtoneList, getIndex());
		listView.setAdapter(adapter);
		// 设置从第getIndex()行开始显示
		listView.setSelection(getIndex());
		listView.setOnItemClickListener(new OnItemClickListener() {

			@SuppressWarnings("static-access")
			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				// 当点击的item是第一个“跟随系统”时
				if (position == 0) {
					// 得到系统默认的消息uri
					Uri defalutUri = manager
							.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
					// 通过URI获得系统默认的Ringtone发出声音
					Ringtone defalutRingtone = manager.getRingtone(
							RingtoneActivity.this, defalutUri);
					defalutRingtone.play();
					ringName = "跟随系统";
					uri = null;
				} else {
					// 当点击的item不是第一个“跟随系统”时,获得的铃声要减一才对
					Ringtone ringtone = manager.getRingtone(position - 1);
					uri = manager.getRingtoneUri(position - 1);
					ringtone.play();
					ringName = ringtone.getTitle(RingtoneActivity.this);

				}
				adapter.first = new int[ringtoneList.size()];
				if (adapter.first[position] == 0) {
					adapter.first[position] = 1;
				} else {
					adapter.first[position] = 0;
				}
				adapter.notifyDataSetChanged();

			}
		});
	}

	/**
	 * 初始化RingtoneManager对象,在listview的点击事件里面,用到了
	 */
	private void initRingtoneManager() {
		manager = new RingtoneManager(this);
		manager.setType(RingtoneManager.TYPE_NOTIFICATION);
		manager.getCursor();
	}

	/**
	 * 得到当前铃声的行数
	 */
	private int getIndex() {
		for (int i = 0; i < ringtoneList.size(); i++) {
			if (SharedPreferenceUtil.getString(RingtoneActivity.this,
					SharedPreferenceUtil.RINGTONE_NAME).equals(
					ringtoneList.get(i))) {
				return i;
			}
		}
		return 0;
	}

	/**
	 * 得到ringtone中的所有消息声音
	 */
	private void getRingtone() {
		manager = new RingtoneManager(this);
		manager.setType(RingtoneManager.TYPE_NOTIFICATION);
		Cursor cursor = manager.getCursor();
		int num = cursor.getCount();
		Log.i("tag", num + "消息音个数");
		ringtoneList = new ArrayList<String>();
		for (int i = -1; i < num; i++) {
			if (i == -1) {
				ringtoneList.add("跟随系统");
			} else {
				Ringtone ringtone = manager.getRingtone(i);
				// Uri uri = manager.getRingtoneUri(i);
				String title = ringtone.getTitle(this);
				ringtoneList.add(title);
			}

		}
	}

	public void allClick(View v) {
		switch (v.getId()) {
		case R.id.back_button:
			finish();
			break;
		case R.id.save:
			if (ringName == "") {
				// 没有改动铃声直接关闭界面
				finish();
			} else {
				// 已经改动uri,如果又选择了跟随系统,则uri为null,其他的就是uri本身
				if (uri == null) {
					SharedPreferenceUtil.setString(RingtoneActivity.this,
							SharedPreferenceUtil.url_string, "");
				} else {
					SharedPreferenceUtil.setString(RingtoneActivity.this,
							SharedPreferenceUtil.url_string, uri.toString());
				}

				Intent intent = new Intent();
				intent.putExtra("ringName", ringName);
				intent.setClass(RingtoneActivity.this, FunctionActivity.class);
				startActivity(intent);
			}
		default:
			break;
		}
	}
}

解释1.

因为listView显示的第一行是一个“追随系统”的item,所以我在适配数据的时候,有些小改变,在i=-1的时候,将ringtoneList添加为“追随系统”,其他的不变。因为进行了这样的处理,那么在点击各个item时候,获得铃声并进行播放时候,要做这样的处理:

Ringtone ringtone = manager.getRingtone(position - 1);

解释2.

最终将选择的铃声uri路径以String的格式存入到sharedPreference中。

在service里面进行设置,如下所示:主要看15--24行。

		NotificationManager notificationManager = (NotificationManager) this
				.getSystemService(Context.NOTIFICATION_SERVICE);
		Notification n = new Notification();
		Intent intent = new Intent(this, FunctionActivity.class);
		intent.putExtra("messageData","messageData" );
		PendingIntent pi = PendingIntent.getActivity(this, 0, intent,
				PendingIntent.FLAG_ONE_SHOT);
		n.contentIntent = pi;

		// n.defaults = Notification.DEFAULT_ALL;
		if (SharedPreferenceUtil
				.getBoolean(this, SharedPreferenceUtil.IS_SOUND)) {

		} else {
			// 如果消息声音开启
			if (!SharedPreferenceUtil.getStringNull(OnlineService.this,
					SharedPreferenceUtil.url_string).equals("")) {
				// 如果选择了其他的系统声音
				n.sound = Uri.parse(SharedPreferenceUtil.getString(
						OnlineService.this, SharedPreferenceUtil.url_string));
			} else {
				// 默认的系统声音
				n.defaults |= Notification.DEFAULT_SOUND;
			}
		}
		if (SharedPreferenceUtil.getBoolean(this,
				SharedPreferenceUtil.IS_VIBRATE)) {

		} else {
			n.defaults |= Notification.DEFAULT_VIBRATE;
		}

		n.flags |= Notification.FLAG_SHOW_LIGHTS;
		n.flags |= Notification.FLAG_AUTO_CANCEL;

		// n.sound=Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, "6");
		n.icon = R.drawable.ic_launcher;
		n.when = System.currentTimeMillis();
		n.tickerText = tickerText;

		n.setLatestEventInfo(this, title, content, pi);
		notificationManager.notify(id, n);
	

注意:如果是要选择其他的声音,直接是n.sound = 其他声音的Uri

这个真的非常重要,就直接这样就可以了,看网上一大堆什么

notification.sound = Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, "6"); //使用系统提供的铃音  

并不能有效果,我也不清楚为什么,如果大家有合理的解释,请告知,嘿嘿。

现在谷歌官方已经不推荐上面的那种notification的做法了,新的做法是下面的这个:

		Bitmap btm = BitmapFactory.decodeResource(getResources(),
				R.drawable.ic_launcher);
		// 这里大图标,小图标刚好相反
		NotificationCompat.Builder builder = new NotificationCompat.Builder(
				this).setSmallIcon(R.drawable.ic_launcher)
				.setContentTitle(title).setContentText(content)
				.setTicker(tickerText);

		if (SharedPreferenceUtil
				.getBoolean(this, SharedPreferenceUtil.IS_SOUND)) {

		} else {
			// 如果消息声音开启
			if (!SharedPreferenceUtil.getStringNull(OnlineService.this,
					SharedPreferenceUtil.url_string).equals("")) {
				// 如果选择了其他的系统声音
				builder.setSound(Uri.parse(SharedPreferenceUtil.getString(
						OnlineService.this, SharedPreferenceUtil.url_string)));
			} else {
				// 默认的系统声音
				builder.setDefaults(Notification.DEFAULT_SOUND);
			}
		}

		if (SharedPreferenceUtil.getBoolean(this,
				SharedPreferenceUtil.IS_VIBRATE)) {

		} else {
			builder.setDefaults(Notification.DEFAULT_VIBRATE);
		}
		// 构建一个Intent
		Intent intent = new Intent(this, FunctionActivity.class);

		intent.putExtra("messageData","messageData" );
		sendData();
		// 封装一个Intent
		PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
				intent, PendingIntent.FLAG_ONE_SHOT);
		// 设置通知主题的意图
		builder.setContentIntent(pendingIntent);
		// 获取通知管理器对象
		NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
		notificationManager.notify(id, builder.build());

关于这个新的notification的用法,你可以参看这个文章:http://blog.csdn.net/harryweasley/article/details/46348363

不过这个有个问题就是,builder.setDefaults()这个方法设置默认的铃声,闪关灯,震动,每次只能设置一次,不能多次调用这个方法来设置。如果有大神知道,请告知我。

解释3:

当点击保存按钮后,就进入到之前的界面,因为我之前的界面是一个viewpager+fragment的一个界面,一个activity里面加入了四个Fragment的这样的一个界面。进入到主activity时候,进行判断:

/**
	 * 选择消息提示音后,跳转到功能界面后,直接将其跳转设置界面
	 */
	private void selectRingtone() {
		String ringName = getIntent().getStringExtra("ringName");
		Log.e("tag", ringName+"传过来的值");
		if (ringName != null) {
			pager.setCurrentItem(2);
		}
	}

直接跳转到第二个Fragment界面。如下图所示:

然后将设置界面的新消息提示音的内容进行改变:

		newSound = (TextView) getActivity().findViewById(R.id.new_sounde_text);
		newSound.setText(SharedPreferenceUtil.getStringSystem(getActivity(),
				SharedPreferenceUtil.RINGTONE_NAME));

		//第一次进入这个页面,下面的方法是不会执行的,因为ringName是null
		String ringName = getActivity().getIntent().getStringExtra("ringName");
		if (ringName != null) {
			newSound.setText(ringName);
			Log.e("tag", ringName+"要保存的值");
			SharedPreferenceUtil.setString(getActivity(),
					SharedPreferenceUtil.RINGTONE_NAME, ringName);
		}

解释4:

你可能注意到,我在RingtoneActivity代码里注释了两行代码,你会发现,当我们每次进入这个RingtoneActivity的时候,都要重新加载数据到arrayList里面,虽然数据不是很多,但是肉眼可以感觉到是有点卡顿的,那么为了防止卡顿,我在进入RingtoneActivity之前的FunctionActivity页面开了一个子线程先加载数据到arrayList里面,定义成static类型。如下所示:

static ArrayList<String> ringtoneList;
	Runnable run = new Runnable() {

		@Override
		public void run() {

			RingtoneManager manager = new RingtoneManager(FunctionActivity.this);
			manager.setType(RingtoneManager.TYPE_NOTIFICATION);
			Cursor cursor = manager.getCursor();
			int num = cursor.getCount();
			Log.i("tag", num + "消息音个数");
			 ringtoneList = new ArrayList<String>();
			for (int i = -1; i < num; i++) {
				if (i == -1) {
					ringtoneList.add("跟随系统");
				} else {
					Ringtone ringtone = manager.getRingtone(i);
					// Uri uri = manager.getRingtoneUri(i);
					String title = ringtone.getTitle(FunctionActivity.this);
					ringtoneList.add(title);
				}

			}

		}
	};

这样在ringtoneActivity中,通过

ringtoneList = FunctionActivity.ringtoneList;

就获得了数据,这样就不会有卡顿了。但是我这个方法用到了static定义变量,这样容易造成oom,具体参看http://blog.csdn.net/harryweasley/article/details/45872685  android内存泄露优化总结

所以我弃用了这个方法,不知道有没有大神可以给个建议呢。

解释5:

当你选择了其他的铃声的时候,再次进入新消息提示音界面时候,是从当前选择的铃声开始展示的,如图所示:

当我选择了Clever这个铃声的时候,我再次进入这个页面,会从Clever这行开始显示。这个功能是这样实现的。嘿嘿,并没有想象的那么难吧,其实listview就自带这个方法的,只需要传入当前item的位置是第几个就行了。

// 设置从第getIndex()行开始显示
		listView.setSelection(getIndex());
/**
	 * 得到当前铃声的行数
	 */
	private int getIndex() {
		for (int i = 0; i < ringtoneList.size(); i++) {
			if (SharedPreferenceUtil.getString(RingtoneActivity.this,
					SharedPreferenceUtil.RINGTONE_NAME).equals(
					ringtoneList.get(i))) {
				return i;
			}
		}
		return 0;
	}

RingtoneAdapter里的内容是这样的:

package jz.his.adapter;

import java.util.ArrayList;

import jz.his.adapter.MessageAdapter.ViewHolder;
import jz.his.jzhis.R;

import android.content.Context;
import android.opengl.Visibility;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class RingtoneAdapter extends BaseAdapter {
	Context context;
	ArrayList<String> list;
	/**
	 * 建立一个数组,默认都为0
	 */
	public int[] first;
	int index;

	public RingtoneAdapter(Context cont, ArrayList<String> arayList, int index) {
		context = cont;
		list = arayList;
		this.index = index;
		first = new int[list.size()];
	}

	class ViewHolder {
		TextView title;
		ImageView image;
	}

	@Override
	public int getCount() {
		return list.size();
	}

	@Override
	public Object getItem(int position) {
		return null;
	}

	@Override
	public long getItemId(int position) {
		return 0;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder holder = null;
		if (convertView == null) {
			holder = new ViewHolder();
			convertView = LayoutInflater.from(context).inflate(
					R.layout.item_ringtone, null);
			holder.title = (TextView) convertView.findViewById(R.id.title);
			holder.image = (ImageView) convertView.findViewById(R.id.image);
			convertView.setTag(holder);
		} else {
			holder = (ViewHolder) convertView.getTag();
		}
		holder.title.setText(list.get(position));
		if (first[position] == 0) {
			holder.image.setVisibility(View.GONE);
		} else {
			holder.image.setVisibility(View.VISIBLE);
			// 当点击其他item后,将index置为-1,则下面的if语句则不会再执行进入了
			index = -1;
		}
		// 第一次进来的时候,让当前item的图片可见
		if (position == index) {
			holder.image.setVisibility(View.VISIBLE);
		}
		return convertView;
	}

}

RingtoneAdapter里进行了判断,是否某个item后面的对勾显示出来。这里当时还是纠结了一会的,最终还是解决了。特此记录。

item_ringtone布局的代码如下所示:

<?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" >

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="5dp" />

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/text"
        android:layout_margin="5dp"
        android:gravity="center_vertical"
        android:text="mingzi"
        android:textSize="15sp" />

    <TextView
        android:id="@+id/text2"
        android:layout_width="wrap_content"
        android:layout_height="5dp"
        android:layout_below="@id/title" />

    <ImageView android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_margin="10dp"
        android:src="@drawable/umeng_socialize_oauth_check_on"
        android:visibility="gone" />

</RelativeLayout>

里面的有两个空白的textView是为了扩开每个item的高度,为了让铃声名字看起来是在中间位置。

activity_ringtone下面的布局代码如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="55dip"
        android:background="@color/balck"
        android:orientation="horizontal" >

        <LinearLayout
            android:id="@+id/back_button"
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:gravity="center_vertical"
            android:onClick="allClick" >

            <ImageView
                android:layout_width="10dip"
                android:layout_height="18dip"
                android:layout_gravity="center"
                android:layout_marginLeft="15dip"
                android:layout_marginRight="10dip"
                android:src="@drawable/icon_left_arrow" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="新消息提示音"
                android:textColor="@color/white"
                android:textSize="20sp" />
        </LinearLayout>

        <Button
            android:id="@+id/save"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:background="@drawable/account_backg"
            android:onClick="allClick"
            android:text="保存"
            android:textColor="@color/white" />
    </RelativeLayout>

    <ListView
        android:id="@+id/ringtone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="none" >
    </ListView>

</LinearLayout>

Button的account_backg代码是:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >  

    <!-- 内部颜色 -->
    <solid android:color="@color/account_green" />
    <!-- 边缘线条颜色 -->
    <stroke
        android:width="1dp"
        android:color="@color/account_green" />
    <!-- 圆角的幅度 -->
    <corners
        android:bottomLeftRadius="5dip"
        android:bottomRightRadius="5dip"
        android:topLeftRadius="5dip"
        android:topRightRadius="5dip" />  

</shape>  

这样基本的功能就写完了,因为是公司整个项目的,所以不能发源码给大家,但是有任何意见或者问题,可以在评论和我沟通,嘿嘿,共同进步嘛。

时间: 2024-08-06 07:50:17

高仿微信新消息提示音功能的相关文章

仿微信新消息提示音

怕有些人不知道怎么进入微信的新消息提示音功能,我这里说下操作步骤: 打开微信----我---设置---新消息提醒---新消息提示音. 经过以上的步骤就进入了这样的界面 具体实现的步骤. 难点之一:获取到手机系统的提示音,并将它们显示在一个listview里面. 参考如下代码: // 获得RingtoneManager对象   RingtoneManager manager = new RingtoneManager(this);   // 设置RingtoneManager对象的类型为TYPE_

高仿微信5.2.1主界面架构 包含消息通知

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/25708045 一哥们去新疆前给了我个任务,就是整这东西,哥们回来了,赶紧做了个,哈哈,可惜没给我带切糕. 新版微信的效果,一眼看上去准备用ViewpagerIndicator来实现,但是需要在Indicator的后面添加消息通知(BadgeView),可惜没有办法自定义Indicator,最后还是自己写了个实现. 主结构:ViewPager和FragmentPagerAdapt

android高仿微信拍照、多选、预览、删除(去除相片)相册功能

先声明授人与鱼不如授人与渔,只能提供一个思路,当然需要源码的同学可以私下有偿问我要源码:QQ:508181017 工作了将近三年时间了,一直没正儿八经的研究系统自带的相册和拍照,这回来个高仿微信的拍照.多选.预览.删除(去除相片)相册功能,之前开发的所有应用都带有这需求,但是一直都不实用!废话就不多说了,先来捋一下思路: 1.拍照能实时保存到本地并实时查询(不必用广播或者服务) 2.拍照保存到到自定义路径并根据不同文件夹显示文件夹下的相片 3.多选规定张数图片 4.用到的集合有: (1).所有相

Android 高仿微信实时聊天 基于百度云推送

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38799363 ,本文出自:[张鸿洋的博客] 一直在仿微信界面,今天终于有幸利用百度云推送仿一仿微信聊天了~~~ 首先特别感谢:weidi1989分享的Android之基于百度云推送IM ,大家可以直接下载:省了很多事哈,本例中也使用了weidi的部分代码,凡是@author way的就是weidi1989的代码~~ 1.效果图 核心功能也就上面的两张图了~~~我拿着手机和模拟器

iOS高仿微信完整源码,网易爱玩APP源码等

iOS精选源码 iOS一种弹出视图效果带动画 一个快速便捷.无侵入.可扩展的动画弹框库 高仿Elk - 旅行货币转换器 iOS内分享的界面.功能一体化解决方案 使用Olami sdk实现一个语音查询股票的iOS程序 iOS高仿微信完整项目源码 分段绘制折线指示图, 点击效果 最新环信推送封装 v3.0[附代码] 仿照网易爱玩APP APP启动视频 iOS优质博客 iOS 一行代码搞定 KVO 前言发现好久没有研究.学习iOS优秀开源代码,现在大部分时间都在写业务代码, 学习其他语言及一些杂七杂八

高仿微信朋友圈

简单介绍 写这个微信朋友圈的目的是今年公司开展了一个趣味运动会,有一个比赛项目是微信点赞.对于我们程序猿来说,这不是送分嘛.于是我们团队光荣的把这个写一个朋友的任务交给了我,要求是类似度百分之99以上,能上传自己定义照片,能更改点赞数与评论数.包含姓名.日期等都能改,于是花费了3天时间写了这个高仿的微信,因为时间关系,代码写的不是非常好.多多谅解.须要的朋友也能够继续完好.因为功能也不少.就不贴代码,直接上图,后面会给下载Demo链接. 主界面 我的相冊 这里提示一下.长按点击我的相冊右上角的相

Android 高仿微信头像截取 打造不一样的自己定义控件

转载请表明出处:http://blog.csdn.net/lmj623565791/article/details/39761281,本文出自:[张鸿洋的博客] 1.概述 前面已经写了关于检測手势识别的文章.假设不了解能够參考:Android 手势检測实战 打造支持缩放平移的图片预览效果(下).首先本篇文章,将对之前博客的ZoomImageView代码进行些许的改动与改善,然后用到我们的本篇博客中去,实现仿微信的头像截取功能.当然了.个人觉得微信的截取头像功能貌似做得不太好.本篇博客准备去其糟粕

Android控件:高仿微信主UI

高仿微信主UI 之前在Android组件:Fragment切换后保存状态 一文中讲到了Fragment切换后,是如何保存原来的状态的,最重要的就是用add方法取代现在各种教程常见的replace方法.然而我发现有不少App都貌似采用ViewPager + Fragment来做主UI的.于是在Android组件:Fragment切换后保存状态 的基础上加入了ViewPager,看了下微信界面,要高仿就尽力模仿到最像,所以也把ActionBar也修改成微信的样子. 先上一张效果图: 布局 我知道微信

Android高仿微信头像裁剪

最近公司的APP很多用户反应无法上传头像,于是打算修改原来头像裁剪的代码.参考微信.QQ.唱吧头像裁剪的操作,决定就仿微信头像裁剪来上传用户头像,在Android大神鸿洋的一篇高仿微信头像的博客(博客地址结尾会贴出来)的基础上加了一些代码,加的代码主要增加如下的功能: 1.增加对大图的处理,缩放到我们裁剪框的大小. 2.裁剪后的图片保存到临时文件里,把临时文件的路径返回到需要处理的界面,因为在三星S4传byte数组返回数据时会闪退,传路径则正常. 3.对有些系统返回旋转过的图片进行处理. 这个功