package org.kymjs.music.ui.fragment;
import org.kymjs.kjframe.KJDB;
import org.kymjs.kjframe.ui.KJFragment;
import org.kymjs.kjframe.ui.ViewInject;
import org.kymjs.kjframe.utils.KJLoger;
import org.kymjs.music.Config;
import org.kymjs.music.R;
import org.kymjs.music.adapter.LrcListAdapter;
import org.kymjs.music.bean.Music;
import org.kymjs.music.service.DownMusicInfo;
import org.kymjs.music.service.DownMusicLrc;
import org.kymjs.music.ui.Main;
import org.kymjs.music.ui.widget.LrcView;
import org.kymjs.music.ui.widget.TabLayout;
import org.kymjs.music.ui.widget.TabLayout.OnViewChangeListener;
import org.kymjs.music.utils.ImageUtils;
import org.kymjs.music.utils.LyricHelper;
import org.kymjs.music.utils.Player;
import org.kymjs.music.utils.PreferenceHelper;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
/**
* 歌词界面
*
* @author kymjs
*/
public class LyricFragment extends KJFragment {
private final SeekThread mSeekThread = new SeekThread();
private final SeekHandle mSeekHandle = new SeekHandle();
private final Player mPlayer = Player.getPlayer();
private final KJDB db = KJDB.create(getActivity(), Config.DB_NAME,
Config.isDebug);
private DownMusicLrc mDownService;
private final DownloadReceiver receiver = new DownloadReceiver();
private final DownloadService conn = new DownloadService();
public static int changeImg = 0; // 更换图片的次数
// 从activity中获取的变量
private FrameLayout.LayoutParams contentParams;
private View lyricView;
private int screenHeight;
// 主体部分的控件
private TabLayout mScrollLayout;
private Button mBtnBack;
private CheckBox mCboxWordImg;
private SeekBar mSeekBarMusic;
private ImageView musicImg;
// 底部栏控件
private View bottomBar;
private ImageView mImgPlay;
private ImageView mImgPrevious;
private ImageView mImgNext;
private ImageView mImgLoop;
private ImageView mImgMenu;
private final String[] loopModeStr = { "单曲播放", "单曲循环", "列表播放", "随机播放" };
// 播放列表部分
private ListView mPlayList;
public LrcListAdapter adapter;
// 歌词main部分
private FrameLayout mLayoutMain;
private TextView mMusicTitle;
private TextView mMusicArtist;
private Button mBtnCollect;
private Button mBtnShared;
// 歌词lyric部分
private LrcView lrcView;
private final LyricHelper lyricHelper = new LyricHelper();
@Override
protected View inflaterView(LayoutInflater arg0, ViewGroup arg1, Bundle arg2) {
View view = arg0.inflate(R.layout.frag_lyric, arg1, false);
return view;
}
// 在onCreate方法中注册歌词下载完成和歌曲xml下载完成的receiver,绑定下载歌词的service
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
IntentFilter filter = new IntentFilter();
filter.addAction(Config.RECEIVER_DOWNLOAD_XML);
filter.addAction(Config.RECEIVER_DOWNLOAD_LYRIC);
getActivity().registerReceiver(receiver, filter);
Intent downService = new Intent(getActivity(), DownMusicLrc.class);
getActivity().bindService(downService, conn, Context.BIND_AUTO_CREATE);
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
public void onDestroy() {
super.onDestroy();
getActivity().unregisterReceiver(receiver);
getActivity().unbindService(conn);
}
@Override
public void initWidget(View parentView) {
mBtnBack = (Button) parentView.findViewById(R.id.lrc_btn_back);
mBtnBack.setOnClickListener(this);
mCboxWordImg = (CheckBox) parentView
.findViewById(R.id.lrc_cbox_wordimg);
mCboxWordImg.setOnClickListener(this);
// 初始化从activity中获取的变量
contentParams = ((Main) getActivity()).contentParams;
lyricView = ((Main) getActivity()).lyricView;
screenHeight = ((Main) getActivity()).screenHeight;
// 初始化主体控件并取消ResideMenu的触摸事件
initScrollLayout(parentView);
((Main) getActivity()).getResideMenu().addIgnoredView(mScrollLayout);
initLrcView(parentView);
initLrcMainView(parentView);
initPlayList(parentView);
initSeekBar(parentView);
initBottomBar(parentView);
}
/**
* 初始化歌词控件
*/
private void initLrcView(View parentView) {
lrcView = (LrcView) parentView.findViewById(R.id.lyric_pager_lrcView);
lrcView.setOnClickListener(this);
lrcView.setLrc(lyricHelper.resolve(mPlayer.getMusic()));
}
/**
* 初始化歌词界面中心部分
*/
private void initLrcMainView(View parentView) {
mLayoutMain = (FrameLayout) parentView.findViewById(R.id.lrc_layout);
mLayoutMain.setOnTouchListener(new LrcTouchlisener());
mMusicTitle = (TextView) parentView.findViewById(R.id.lrc_main_title);
mMusicTitle.setText(mPlayer.getMusic().getTitle());
mMusicArtist = (TextView) parentView.findViewById(R.id.lrc_main_artist);
mMusicArtist.setText(mPlayer.getMusic().getArtist());
mBtnCollect = (Button) parentView.findViewById(R.id.lrc_main_collect);
mBtnCollect.setBackgroundResource(ImageUtils.getBtnCollectBg(mPlayer
.getMusic().getCollect() != 0));
mBtnCollect.setOnClickListener(this);
mBtnShared = (Button) parentView.findViewById(R.id.lrc_main_share);
mBtnShared.setOnClickListener(this);
musicImg = (ImageView) parentView.findViewById(R.id.lrc_image);
}
/**
* 初始化播放列表控件
*/
private void initPlayList(View parentView) {
mPlayList = (ListView) parentView.findViewById(R.id.lrc_pager_list);
adapter = new LrcListAdapter(getActivity());
mPlayList.setAdapter(adapter);
mPlayList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
((Main) getActivity()).mPlayersService.play(mPlayer.getList(),
position);
}
});
}
/**
* 初始化主体界面
*/
private void initScrollLayout(View parentView) {
int defScreen = 1; // 默认显示第二屏
mScrollLayout = (TabLayout) parentView.findViewById(R.id.lrc_tablayout);
mScrollLayout.setToScreen(defScreen);
int scrollChildCount = mScrollLayout.getChildCount();
final RadioGroup circles = (RadioGroup) parentView
.findViewById(R.id.lrc_circle_layout);
for (int i = 0; i < scrollChildCount; i++) {
circles.addView(getCircles());
}
// 小点的默认显示
((RadioButton) circles.getChildAt(defScreen)).setChecked(true);
mScrollLayout.SetOnViewChangeListener(new OnViewChangeListener() {
@Override
public void OnViewChange(int view) {
RadioButton circle = (RadioButton) circles.getChildAt(view);
circle.setChecked(true);
if (view == 0) {
} else if (view == 1) {
mCboxWordImg.setChecked(true);
} else if (view == 2) {
mCboxWordImg.setChecked(false);
}
}
});
}
/**
* 获取一个"小点"
*/
private RadioButton getCircles() {
RadioButton circle = new RadioButton(getActivity());
int dimen5 = (int) getResources().getDimension(R.dimen.space_5);
int dimen3 = (int) getResources().getDimension(R.dimen.space_3);
RadioGroup.LayoutParams params = new RadioGroup.LayoutParams(dimen5,
dimen5);
params.setMargins(dimen3, 0, dimen3, 0);
circle.setLayoutParams(params);
circle.setBackgroundResource(R.drawable.selector_rbtn_circle);
return circle;
}
/**
* 初始化歌词界面底部栏
*/
private void initBottomBar(View parentView) {
bottomBar = parentView.findViewById(R.id.lrc_bottom);
// 防止底部栏点击事件穿透到Activity上
bottomBar.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
mImgPlay = (ImageView) parentView.findViewById(R.id.lrc_btn_play);
mImgPlay.setImageResource(ImageUtils.getBtnPlayBg());
mImgPlay.setOnClickListener(this);
mImgPrevious = (ImageView) parentView.findViewById(R.id.lrc_btn_prev);
mImgPrevious.setOnClickListener(this);
mImgNext = (ImageView) parentView.findViewById(R.id.lrc_btn_next);
mImgNext.setOnClickListener(this);
mImgLoop = (ImageView) parentView.findViewById(R.id.lrc_btn_loop);
mImgLoop.setImageResource(ImageUtils.getImgLoopBg(getActivity()));
mImgLoop.setOnClickListener(this);
mImgMenu = (ImageView) parentView.findViewById(R.id.lrc_btn_menu);
mImgMenu.setOnClickListener(this);
}
/**
* 初始化歌词界面底部滑动条
*/
private void initSeekBar(View parentView) {
mSeekHandle.post(mSeekThread);
mSeekBarMusic = (SeekBar) parentView
.findViewById(R.id.lrc_seekbar_music);
mSeekBarMusic.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
mPlayer.seekTo(seekBar.getProgress());
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
mPlayer.seekTo(seekBar.getProgress());
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {}
});
}
/**
* SeekBar的控制器,随歌曲播放改变
*/
class SeekThread implements Runnable {
@Override
public void run() {
Message msg = Message.obtain();
msg.arg1 = mPlayer.getDuration(); // 最大值
msg.arg2 = mPlayer.getCurrentPosition(); // 进度
mSeekHandle.sendMessage(msg);
}
}
@SuppressLint("HandlerLeak")
class SeekHandle extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
mSeekBarMusic.setMax(msg.arg1);
mSeekBarMusic.setProgress(msg.arg2);
lrcView.seekLrcToTime(msg.arg2);
// mTextProg.setText(StringUtils.timeFormat(msg.arg2));
// mTextTotal.setText(StringUtils.timeFormat(msg.arg1));
mSeekHandle.post(mSeekThread);
}
}
@Override
public void widgetClick(View parentView) {
Music music = mPlayer.getMusic();
switch (parentView.getId()) {
case R.id.lrc_main_share:
ViewInject.toast("分享功能暂无");
break;
case R.id.lrc_main_collect:
music.setCollect((music.getCollect() + 1) % 2);
db.update(music, "id = '" + music.getId() + "'");
mBtnCollect.setBackgroundResource(ImageUtils.getBtnCollectBg(music
.getCollect() != 0));
Config.changeCollectInfo = true;
Config.changeMusicInfo = true;
getActivity().sendBroadcast(
new Intent(Config.RECEIVER_UPDATE_MUSIC_LIST));
break;
case R.id.lrc_btn_back:
((Main) getActivity()).wantScroll((Main) getActivity());
break;
case R.id.lrc_cbox_wordimg:
mScrollLayout.scrollToScreen(mCboxWordImg.isChecked() ? 1 : 2);
break;
case R.id.lrc_btn_play:
if (mPlayer.getPlaying() == Config.PLAYING_STOP) {
((Main) getActivity()).mPlayersService.play();
} else if (mPlayer.getPlaying() == Config.PLAYING_PLAY) {
((Main) getActivity()).mPlayersService.pause();
} else {
((Main) getActivity()).mPlayersService.replay();
}
mImgPlay.setImageResource(ImageUtils.getBtnPlayBg());
break;
case R.id.lrc_btn_prev:
((Main) getActivity()).mPlayersService.previous();
break;
case R.id.lrc_btn_next:
((Main) getActivity()).mPlayersService.next();
break;
case R.id.lrc_btn_loop:
int curLoop = PreferenceHelper.readInt(getActivity(),
Config.LOOP_MODE_FILE, Config.LOOP_MODE_KEY,
Config.MODE_REPEAT_ALL);
PreferenceHelper.write(getActivity(), Config.LOOP_MODE_FILE,
Config.LOOP_MODE_KEY, (curLoop + 1) % 4);
mImgLoop.setImageResource(ImageUtils.getImgLoopBg(getActivity()));
ViewInject.toast(loopModeStr[(curLoop + 1) % 4]);
break;
case R.id.lrc_btn_menu:
ViewInject.toast("正在更换歌曲图片");
ImageUtils.setNetBg(getActivity(), musicImg, music.getTitle(),
changeImg++);
break;
case R.id.lyric_pager_lrcView:
// 如果没有歌词
if (Config.LRC_TEXT.equals(lrcView.getLoadingTipText())) {
if (music.getLrcId() != null && music.getLrcId().length() > 2) {
// 如果歌曲信息中已经有路径,则直接下载
mDownService.downLrc(music);
} else {
Intent downIntent = new Intent(getActivity(),
DownMusicInfo.class);
downIntent.putExtra("music", music);
getActivity().startService(downIntent);
}
}
break;
}
}
/**
* 刷新歌词界面
*/
public void refreshLrcView() {
// 同样的问题,无法直接刷新,需要重新setadapter();
// if (adapter != null) {
// adapter.refreshLrcAdapter();
// }
mPlayList.setAdapter(new LrcListAdapter(getActivity()));
mMusicTitle.setText(mPlayer.getMusic().getTitle());
mMusicArtist.setText(mPlayer.getMusic().getArtist());
mBtnCollect.setBackgroundResource(ImageUtils.getBtnCollectBg(mPlayer
.getMusic().getCollect() != 0));
mImgPlay.setImageResource(ImageUtils.getBtnPlayBg());
lrcView.setLrc(lyricHelper.resolve(mPlayer.getMusic()));
ImageUtils.setNetBg(getActivity(), musicImg, mPlayer.getMusic()
.getTitle());
}
class DownloadService implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mDownService = ((DownMusicLrc.DownLrcHolder) service).getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
ViewInject.toast("歌词下载异常,请重试");
}
}
class DownloadReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Config.RECEIVER_DOWNLOAD_XML.equals(intent.getAction())) {
Music music = (Music) intent.getSerializableExtra("music");
mDownService.downLrc(music);
} else {
// 下载完成,更新控件显示
lrcView.setLrc(new LyricHelper().resolve(mPlayer.getMusic()));
}
}
}
/***********************************************************************
*
* 歌词界面主要部分的点击事件(用于手势下拉)
*
***********************************************************************/
/** 用于计算手指滑动的速度。 */
private VelocityTracker mVelocityTracker;
/** 滚动显示和隐藏lrc时,手指滑动需要达到的速度。 */
public static final int SNAP_VELOCITY = 200;
/** 此时Y坐标 */
float yDown = 0, yMove = 0, yUp = 0;
class LrcTouchlisener implements OnTouchListener {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (mScrollLayout.getCurScreen() == 1) {
createVelocityTracker(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 手指按下时记录此时Y坐标
yDown = event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
// 手指移动时,对比按下时的坐标,计算出移动的距离,来调整menu的leftMargin值,从而显示和隐藏menu
yMove = event.getRawY();
int distanceY = (int) (yMove - yDown);
contentParams.topMargin = distanceY;
lyricView.setLayoutParams(contentParams);
break;
case MotionEvent.ACTION_UP:
yUp = event.getRawY();
changeMenuState();
recycleVelocityTracker();
break;
}
return true;
} else {
return false;
}
}
}
/**
* 是否应该打开
*/
private void changeMenuState() {
float y = yUp - yDown;
KJLoger.debug("y=" + y + "-----yup=" + yUp + "-------yDown=" + yDown
+ "-----歌词界面状态" + ((Main) getActivity()).isOpen);
if ((y > screenHeight / 2 && getScrollVelocity() > 0)
|| getScrollVelocity() > SNAP_VELOCITY) {
// 关闭的(歌词界面正在呈现即将转入content界面)
((Main) getActivity()).isOpen = true;
} else {
// 打开的(内容界面正在呈现即将转入lyric界面)
((Main) getActivity()).isOpen = false;
}
((Main) getActivity()).wantScroll((Main) getActivity());
}
/**
* 获取手指在content界面滑动的速度。
*
* @return 滑动速度,以每秒钟移动了多少像素值为单位。
*/
private int getScrollVelocity() {
mVelocityTracker.computeCurrentVelocity(1000);
int velocity = (int) mVelocityTracker.getYVelocity();
// return Math.abs(velocity);
return velocity;
}
/**
* 创建VelocityTracker对象,并将触摸content界面的滑动事件加入到VelocityTracker当中。
*/
private void createVelocityTracker(MotionEvent event) {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(event);
}
/**
* 回收VelocityTracker对象。
*/
private void recycleVelocityTracker() {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
}