实现效果如图:
思路:
上方是一个LinearLayout,里面放了4个自定义按钮。
下方是一个自定义seekbar
先来实现自定义按钮
public class IconCustomPreference extends RelativeLayout
{
private Drawable mMainIconSrc = null;
private Drawable mSubIconSrc = null;
private String mSubText = "";
private ImageView mMainImageView = null;
private ImageView mSubImageView = null;
private TextView mSubTextView = null;
private Context mContext = null;
private LayoutParams mParams = null;
private int mMainId = 0x120000;
public IconCustomPreference(Context context, AttributeSet attrs)
{
super(context, attrs);
mContext = context;
init(attrs);
}
private void init(AttributeSet attrs)
{
TypedArray ta = mContext.obtainStyledAttributes(attrs, R.styleable.IconCustomPreference);
mMainIconSrc = ta.getDrawable(R.styleable.IconCustomPreference_mainIconSrc);
mSubIconSrc = ta.getDrawable(R.styleable.IconCustomPreference_subIconSrc);
mSubText = ta.getString(R.styleable.IconCustomPreference_subText);
mParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
mParams.addRule(CENTER_HORIZONTAL);
mMainImageView = new ImageView(mContext);
if(mMainIconSrc == null)
{
mMainIconSrc = mContext.getResources().getDrawable(R.drawable.pro_exposure_selector);
}
if(mSubIconSrc == null)
{
mSubIconSrc = mContext.getResources().getDrawable(R.drawable.pro_sub_auto_selector);
}
mMainImageView.setImageDrawable(mMainIconSrc);
mMainImageView.setId(mMainId);
addView(mMainImageView, mParams);
mParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
mParams.addRule(CENTER_HORIZONTAL);
mParams.addRule(BELOW, mMainId);
mSubImageView = new ImageView(mContext);
mSubImageView.setImageDrawable(mSubIconSrc);
addView(mSubImageView, mParams);
mSubTextView = new TextView(mContext);
addView(mSubTextView, mParams);
mSubTextView.setVisibility(View.GONE);
mSubTextView.setTextSize(10);
mSubTextView.setTextColor(Color.WHITE);
ta.recycle();
}
public void setSubImageSrc(int imageId)
{
mSubTextView.setVisibility(View.GONE);
mSubImageView.setVisibility(View.VISIBLE);
mSubImageView.setImageResource(imageId);
}
public void setSubTextSrc(int resid)
{
mSubImageView.setVisibility(View.GONE);
mSubTextView.setVisibility(View.VISIBLE);
mSubTextView.setText(resid);
}
public void setSelected(boolean select)
{
if(select)
{
mSubTextView.setTextColor(Color.YELLOW);
}else
{
mSubTextView.setTextColor(Color.WHITE);
}
mMainImageView.setSelected(select);
mSubImageView.setSelected(select);
}
}
点击效果:
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 按下状态-->
<item
android:state_pressed="true"
android:drawable="@drawable/pro_exposure_pressed" />
<!-- 有焦点 -->
<item
android:state_focused="true"
android:drawable="@drawable/pro_exposure_pressed"/>
<item
android:state_selected="true"
android:drawable="@drawable/pro_exposure_pressed"/>
<!-- 普通无焦点状态 -拖动按钮-->
<item
android:drawable="@drawable/pro_exposure_normal" />
</selector>
然后放置在主布局的布局文件中
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ws="http://schemas.android.com/apk/res/com.jimmy.jpower"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="@+id/pro_setting_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/pro_settings_bg"
android:orientation="vertical"
android:layout_alignParentRight="true"
android:paddingTop="16dip"
android:layout_marginTop="40dip"
android:layout_marginRight="16dip">
<com.ws.jpower.widget.seekbar.IconCustomPreference
android:id="@+id/pro_iso_id"
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="1"
android:layout_gravity="center_horizontal"
ws:mainIconSrc="@drawable/pro_iso_selector"
ws:subIconSrc="@drawable/pro_sub_auto_selector"
ws:subText="@string/pro_iso_100"/>
<com.ws.jpower.widget.seekbar.IconCustomPreference
android:id="@+id/pro_wb_id"
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="1"
android:layout_gravity="center_horizontal"
ws:mainIconSrc="@drawable/pro_wb_selector"
ws:subIconSrc="@drawable/pro_sub_auto_selector"
ws:subText="@string/pro_iso_100"/>
<com.ws.jpower.widget.seekbar.IconCustomPreference
android:id="@+id/pro_exposure_id"
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="1"
android:layout_gravity="center_horizontal"
ws:mainIconSrc="@drawable/pro_exposure_selector"
ws:subIconSrc="@drawable/pro_sub_auto_selector"
ws:subText="@string/pro_iso_100"/>
<com.ws.jpower.widget.seekbar.IconCustomPreference
android:id="@+id/pro_ss_id"
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="1"
android:layout_gravity="center_horizontal"
ws:mainIconSrc="@drawable/pro_ss_selector"
ws:subIconSrc="@drawable/pro_sub_auto_selector"
ws:subText="@string/pro_iso_100"/>
<ImageView
android:id="@+id/pro_setting_reset_id"
android:layout_width="wrap_content"
android:layout_height="0dip"
android:src="@drawable/pro_setting_reset_selector"
android:layout_weight="1"
android:layout_gravity="center_horizontal"/>
</LinearLayout>
<RelativeLayout
android:id="@+id/pro_seekbar_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/pro_single_settings_bg"
android:visibility="gone"
android:layout_alignParentBottom="true"
android:layout_marginBottom="40dip">
</RelativeLayout>
</RelativeLayout>
然后定义seekbar。实际上我们只需要在seekbar上加一个包含图片或文字素材的LinearLayout局部即可是不是很简单。
public class JSeekbarWithTitle extends LinearLayout
{
private Context mContext = null;
private LinearLayout mTitleView = null;
private SeekBar mSeekBar = null;
private int mType = 0;
private ImageView mAutoIv = null;
private TextView[] mLevels = null;
private int [] mLevelsId = null;
private ImageView[] mLevelIvs = null;
private int mCurrentProgress = 10;
private OnCustomSeekBarChangedListener listener = null;
private boolean mHasAutoIv = true;
public JSeekbarWithTitle(Context context,int[] levelids, int type, boolean hasAutoIv)
{
super(context);
// TODO Auto-generated constructor stub
mContext = context;
mType = type;
mLevelsId = levelids;
mHasAutoIv = hasAutoIv;
initView();
}
private void initView()
{
setOrientation(LinearLayout.VERTICAL);
// TODO Auto-generated method stub
mTitleView = new LinearLayout(mContext);
mTitleView.setOrientation(LinearLayout.HORIZONTAL);
mTitleView.setGravity(Gravity.CENTER_VERTICAL);
LayoutParams params = new LayoutParams(0, LayoutParams.WRAP_CONTENT, 1);
if(mHasAutoIv)
{
mAutoIv = new ImageView(mContext);
mAutoIv.setImageResource(R.drawable.pro_auto_selector);
mAutoIv.setSelected(true);
mTitleView.addView(mAutoIv, params);
}
if(mLevelsId != null)
{
if(mType == 0)
{
mLevels = new TextView[mLevelsId.length];
for(int i = 0; i < mLevelsId.length; i++)
{
TextView levelView = new TextView(mContext);
levelView.setText(mLevelsId[i]);
levelView.setTextColor(Color.WHITE);
levelView.setGravity(Gravity.CENTER);
levelView.setTextSize(14);
mLevels[i] = levelView;
mTitleView.addView(levelView, params);
}
}else
{
mLevelIvs = new ImageView[mLevelsId.length];
for(int i = 0; i < mLevelsId.length; i++)
{
ImageView levelImageView = new ImageView(mContext);
levelImageView.setImageResource(mLevelsId[i]);
mLevelIvs[i] = levelImageView;
mTitleView.addView(levelImageView, params);
}
}
}
LayoutParams paramTitleView = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
paramTitleView.leftMargin = DensityUtil.dip2px(mContext, 8);
paramTitleView.rightMargin = DensityUtil.dip2px(mContext, 8);
paramTitleView.topMargin = DensityUtil.dip2px(mContext, 8);
addView(mTitleView,paramTitleView);
View view = LayoutInflater.from(mContext).inflate(R.layout.pro_seekbar, null);
mSeekBar = (SeekBar) view.findViewById(R.id.pro_seekbar_id);
//mSeekBar.setProgressDrawable(mContext.getResources().getDrawable(R.drawable.seekbar_define_style));
mSeekBar.setThumb(mContext.getResources().getDrawable(R.drawable.pro_iso_thumb));
mSeekBar.setOnSeekBarChangeListener(mSeekBarChangeListener);
//mSeekBar.setProgress(mCurrentProgress);
setCustomProgress(0);
LayoutParams paramSeekBar = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
paramSeekBar.bottomMargin = DensityUtil.dip2px(mContext, 8);
addView(mSeekBar,paramSeekBar);
}
public void setSeekBarThumb(Drawable drawable)
{
if(mSeekBar != null)
{
mSeekBar.setThumb(drawable);
}
}
private OnSeekBarChangeListener mSeekBarChangeListener = new OnSeekBarChangeListener()
{
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
{
// TODO Auto-generated method stub
mCurrentProgress = progress;
}
@Override
public void onStartTrackingTouch(SeekBar seekBar)
{
// TODO Auto-generated method stub
}
@Override
public void onStopTrackingTouch(SeekBar seekBar)
{
// TODO Auto-generated method stub
setCustomProgress(mCurrentProgress);
}
};
private void setCustomProgress(int progress)
{
Log.e("setCustomProgress", "setCustomProgress progress = " + progress);
int leavelCount = mLevelsId.length + 1;
if(!mHasAutoIv)
{
leavelCount = mLevelsId.length;
}
float leavelUnit = 100/leavelCount;
resetSelected();
Log.e("setCustomProgress", "setCustomProgress leavelUnit = " + leavelUnit);
int leave = (int)(progress/leavelUnit);
Log.e("setCustomProgress", "setCustomProgress leave = " + leave);
if(leave == 0 && mHasAutoIv)
{
mAutoIv.setSelected(true);
}else
{
int positon = leave - 1;
if(!mHasAutoIv)
{
positon = leave;
}
if(positon > mLevelsId.length -1)
positon = mLevelsId.length -1;
if(mLevels != null)
{
mLevels[positon].setTextColor(Color.YELLOW);;
}else if(mLevelIvs != null)
{
mLevelIvs[positon].setSelected(true);
}
}
int count = (int)(progress*leavelCount/100);
Log.e("setCustomProgress", "setCustomProgress count = " + count);
Log.e("setCustomProgress", "setCustomProgress leavelCount = " + leavelCount);
float rawProgress = count*(100/leavelCount) + 50/leavelCount;
Log.e("setCustomProgress", "setCustomProgress rawProgress = " + rawProgress);
float lastProgress = (rawProgress < 100)? (rawProgress): 100- 50/leavelCount;//(progress + 50/leavelCount) < 100 ? (progress + 50/leavelCount):(100- 50/leavelCount);//(int)(leavelUnit*(leave+1) - leavelUnit/2);
Log.e("setCustomProgress", "setCustomProgress lastProgress = " + lastProgress);
mSeekBar.setProgress((int)lastProgress);//回弹
if(listener != null)
{
if(mHasAutoIv)
{
count--;
}
listener.onCustomChange(count);
}
}
private void resetSelected()
{
if(mHasAutoIv)
{
mAutoIv.setSelected(false);
}
if(mLevelIvs != null)
{
for(int i = 0; i < mLevelIvs.length; i++)
{
mLevelIvs[i].setSelected(false);
}
}
if(mLevels != null)
{
for(int i = 0; i < mLevels.length; i++)
{
mLevels[i].setTextColor(Color.WHITE);
}
}
}
public void setCustomSeekBarChaneedListener(OnCustomSeekBarChangedListener listener)
{
this.listener = listener;
}
interface OnCustomSeekBarChangedListener
{
void onCustomChange(int level);
}
}
pro_seekbar.xml
<SeekBar xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:progressDrawable="@drawable/pro_seekbar_define_style"
android:maxHeight="20dip"
android:minHeight="20dip"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:max="100"
android:thumb="@drawable/pro_seekbar_thumb"
android:id="@+id/pro_seekbar_id"/>
使用:
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;
import com.jimmy.jpower.R;
import com.jimmy.jpower.widget.seekbar.JSeekbarWithTitle.OnCustomSeekBarChangedListener;
public class SeekbarActivity extends Activity implements OnClickListener,OnCustomSeekBarChangedListener
{
private LinearLayout mSettingView = null;
private RelativeLayout mSeekBarView = null;
private IconCustomPreference mISOIv = null;
private IconCustomPreference mEVIv = null;
private IconCustomPreference mSSIv = null;
private IconCustomPreference mWBIv = null;
private ImageView mSettingRestoreIv = null;
private JSeekbarWithTitle mWbSeekbar = null;
private JSeekbarWithTitle mISOSeekbar = null;
private JSeekbarWithTitle mEXSeekbar = null;
private JSeekbarWithTitle mSSeekbar = null;
RelativeLayout.LayoutParams params = null;
private static final int ISO_ID = 0;
private static final int WB_ID = 1;
private static final int EV_ID = 2;
private static final int S_ID = 3;
private static final int RESET_ID = -1;
int wbids[] = {R.drawable.pro_wb_cloudy_selector,R.drawable.pro_wb_daylight_selector,
R.drawable.pro_wb_incandescent_selector,R.drawable.pro_wb_fluorescent_selector};//getResources().getIntArray(R.array.pro_wb_icons);
int wbsubids[] = {R.drawable.pro_wb_sub_cloudy_selector,R.drawable.pro_wb_sub_daylight_selector,
R.drawable.pro_wb_sub_incandescent_selector,R.drawable.pro_wb_sub_fluorescent_selector};
int isoids[] = {R.string.pro_iso_100,R.string.pro_iso_200,
R.string.pro_iso_400,R.string.pro_iso_800,R.string.pro_iso_1600};
int isexds[] = {R.string.pro_ev_m_3,R.string.pro_ev_m_2,
R.string.pro_ev_m_1,R.string.pro_ev_0,R.string.pro_ev_p_1,R.string.pro_ev_p_2,R.string.pro_ev_p_3};
int currentId = -1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_seekbar);
mSettingView = (LinearLayout) findViewById(R.id.pro_setting_view);
mSeekBarView = (RelativeLayout) findViewById(R.id.pro_seekbar_view);
mISOIv = (IconCustomPreference) findViewById(R.id.pro_iso_id);
mISOIv.setOnClickListener(this);
mEVIv = (IconCustomPreference) findViewById(R.id.pro_exposure_id);
mEVIv.setOnClickListener(this);
mEVIv.setSubTextSrc(isexds[3]);
mSSIv = (IconCustomPreference) findViewById(R.id.pro_ss_id);
mSSIv.setOnClickListener(this);
mWBIv = (IconCustomPreference) findViewById(R.id.pro_wb_id);
mWBIv.setOnClickListener(this);
mSettingRestoreIv = (ImageView) findViewById(R.id.pro_setting_reset_id);
mSettingRestoreIv.setOnClickListener(this);
mWbSeekbar = new JSeekbarWithTitle(this, wbids, 1,true);
mWbSeekbar.setCustomSeekBarChaneedListener(this);
mISOSeekbar = new JSeekbarWithTitle(this, isoids, 0,true);
mISOSeekbar.setCustomSeekBarChaneedListener(this);
mEXSeekbar = new JSeekbarWithTitle(this, isexds, 0,false);
mEXSeekbar.setCustomSeekBarChaneedListener(this);
params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
}
/**
* 用Handler来更新UI
*/
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
if(msg.what == 1)
{
Animation anim=AnimationUtils.loadAnimation(SeekbarActivity.this,R.anim.pro_push_left_in);
//mSeekBarView.startAnimation(anim);
mSeekBarView.setAnimation(anim);
mSeekBarView.setVisibility(View.VISIBLE);
}
}
};
@Override
public void onClick(View v)
{
int id = v.getId();
if(currentId == id)
{
return;
}
currentId = id;
mISOIv.setSelected(false);
mEVIv.setSelected(false);
mSSIv.setSelected(false);
mWBIv.setSelected(false);
Animation anim = AnimationUtils.loadAnimation(this,R.anim.pro_push_right_out);
if(mSeekBarView.getVisibility() != View.GONE)
{
mSeekBarView.setAnimation(anim);
mSeekBarView.setVisibility(View.GONE);
}
mSeekBarView.removeAllViews();
switch(id)
{
case R.id.pro_iso_id:
mISOIv.setSelected(true);
mSeekBarView.addView(mISOSeekbar, params);
mISOSeekbar.setSeekBarThumb(getResources().getDrawable(R.drawable.pro_iso_thumb));
handler.sendEmptyMessageDelayed(1, 400);
break;
case R.id.pro_exposure_id:
mEVIv.setSelected(true);
mSeekBarView.addView(mEXSeekbar, params);
mEXSeekbar.setSeekBarThumb(getResources().getDrawable(R.drawable.pro_ae_thumb));
handler.sendEmptyMessageDelayed(1, 400);
break;
case R.id.pro_ss_id:
mSSIv.setSelected(true);
mSeekBarView.addView(mWbSeekbar, params);
mWbSeekbar.setSeekBarThumb(getResources().getDrawable(R.drawable.pro_ss_thumb));
handler.sendEmptyMessageDelayed(1, 400);
break;
case R.id.pro_wb_id:
mWBIv.setSelected(true);
mSeekBarView.addView(mWbSeekbar, params);
mWbSeekbar.setSeekBarThumb(getResources().getDrawable(R.drawable.pro_wb_thumb));
handler.sendEmptyMessageDelayed(1, 400);
break;
case R.id.pro_setting_reset_id:
mSeekBarView.setVisibility(View.GONE);
resetSetting();
break;
}
}
private void resetSetting()
{
mISOIv.setSubImageSrc(R.drawable.pro_sub_auto_selector);
mSSIv.setSubImageSrc(R.drawable.pro_sub_auto_selector);
mWBIv.setSubImageSrc(R.drawable.pro_sub_auto_selector);
mEVIv.setSubTextSrc(isexds[3]);
}
@Override
public void onCustomChange(int level)
{
switch(currentId)
{
case R.id.pro_iso_id:
if(level < 0)
{
mISOIv.setSubImageSrc(R.drawable.pro_sub_auto_selector);
}
else
{
mISOIv.setSubTextSrc(isoids[level]);
}
break;
case R.id.pro_exposure_id:
if(level < 0)
{
mEVIv.setSubImageSrc(R.drawable.pro_sub_auto_selector);
}
else
{
mEVIv.setSubTextSrc(isexds[level]);
}
break;
case R.id.pro_ss_id:
if(level < 0)
{
mSSIv.setSubImageSrc(R.drawable.pro_sub_auto_selector);
}
else
{
mSSIv.setSubImageSrc(wbsubids[level]);
}
mSSIv.setSelected(true);
break;
case R.id.pro_wb_id:
if(level < 0)
{
mWBIv.setSubImageSrc(R.drawable.pro_sub_auto_selector);
}
else
{
mWBIv.setSubImageSrc(wbsubids[level]);
}
break;
case R.id.pro_setting_reset_id:
break;
}
}
}