mirror of
https://gitee.com/houstudio/Cdroid.git
synced 2024-11-29 18:59:14 +08:00
add optionpicker
This commit is contained in:
parent
6fc78ac680
commit
c281bf55fa
@ -14,11 +14,12 @@ namespace R{
|
||||
static constexpr int often = 0x00002715 ;/*10005*/
|
||||
static constexpr int care = 0x00002716 ;/*10006*/
|
||||
static constexpr int favorite = 0x00002717 ;/*10007*/
|
||||
static constexpr int options = 0x00002718 ;/*10008*/
|
||||
static constexpr int numpicker = 0x00002718 ;/*10008*/
|
||||
static constexpr int text1 = 0x00002719 ;/*10009*/
|
||||
static constexpr int text2 = 0x0000271A ;/*10010*/
|
||||
static constexpr int content = 0x0000271B ;/*10011*/
|
||||
static constexpr int optionsContainer = 0x0000271C ;/*10012*/
|
||||
static constexpr int option1 = 0x0000271B ;/*10011*/
|
||||
static constexpr int option2 = 0x0000271C ;/*10012*/
|
||||
static constexpr int option3 = 0x0000271D ;/*10013*/
|
||||
};/*namespace id*/
|
||||
|
||||
namespace strings{
|
||||
|
@ -1,29 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/relativeLayout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:background="#111111"
|
||||
android:layout_marginHorizontal="10dp"
|
||||
android:layout_marginVertical="10dp">
|
||||
<NumberPicker
|
||||
android:id="@+id/options"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@id/text1"/>
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<NumberPicker
|
||||
android:id="@+id/numpicker"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@id/text1"/>
|
||||
<TextView
|
||||
android:id="@+id/text1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@id/text2"
|
||||
android:text="护理"/>
|
||||
android:id="@+id/text1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="1dp"
|
||||
android:layout_above="@id/text2"
|
||||
android:gravity="center"
|
||||
android:textSize="32dp"
|
||||
android:textColor="white"
|
||||
android:paddingVertical="5dp"
|
||||
android:background="#121212"/>
|
||||
<TextView
|
||||
android:id="@+id/text2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginVertical="5dp"
|
||||
android:text="收藏"/>
|
||||
</RelativeLayout>
|
||||
android:id="@+id/text2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginTop="1dp"
|
||||
android:paddingVertical="5dp"
|
||||
android:gravity="center"
|
||||
android:textSize="32dp"
|
||||
android:background="#181818"/>
|
||||
</merge>
|
||||
|
||||
|
@ -3,34 +3,31 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
>
|
||||
<FrameLayout
|
||||
android:id="@+id/content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_width="match_parent"
|
||||
<OptionPicker
|
||||
android:id="@+id/option1"
|
||||
android:layout_width="240dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_above="@+id/optionsContainer"
|
||||
>
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:scaleType="center"
|
||||
android:src="@mipmap/chenshan"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Hello world"
|
||||
android:layout_gravity="right|center"/>
|
||||
<NumberPicker
|
||||
android:id="@+id/options"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
/>
|
||||
</FrameLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/optionsContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true">
|
||||
</LinearLayout>
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:background="#112233"
|
||||
android:text2="温度"
|
||||
/>
|
||||
<OptionPicker
|
||||
android:id="@+id/option2"
|
||||
android:layout_width="240dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_toRightOf="@id/option1"
|
||||
android:background="#332211"
|
||||
android:text2="漂洗"
|
||||
/>
|
||||
<OptionPicker
|
||||
android:id="@+id/option3"
|
||||
android:layout_width="240dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_toRightOf="@id/option2"
|
||||
android:text2="转速"
|
||||
|
||||
/>
|
||||
</RelativeLayout>
|
||||
|
@ -8,10 +8,11 @@
|
||||
<id name="often">0x00002715</id>
|
||||
<id name="care">0x00002716</id>
|
||||
<id name="favorite">0x00002717</id>
|
||||
<id name="options">0x00002718</id>
|
||||
<id name="numpicker">0x00002718</id>
|
||||
<id name="text1">0x00002719</id>
|
||||
<id name="text2">0x0000271a</id>
|
||||
<id name="content">0x0000271b</id>
|
||||
<id name="optionsContainer">0x0000271c</id>
|
||||
<id name="option1">0x0000271b</id>
|
||||
<id name="option2">0x0000271c</id>
|
||||
<id name="option3">0x0000271d</id>
|
||||
</resources>
|
||||
|
||||
|
110
apps/w9/optionpicker.cc
Normal file
110
apps/w9/optionpicker.cc
Normal file
@ -0,0 +1,110 @@
|
||||
#include <optionpicker.h>
|
||||
#include <cdtypes.h>
|
||||
#include <cdlog.h>
|
||||
#include <R.h>
|
||||
|
||||
DECLARE_WIDGET(OptionPicker)
|
||||
OptionPicker::OptionPicker(int w,int h):RelativeLayout(w,h){
|
||||
|
||||
}
|
||||
|
||||
OptionPicker::OptionPicker(Context*ctx,const AttributeSet&attr):RelativeLayout(ctx,attr){
|
||||
LayoutInflater::from(ctx)->inflate("@layout/optionitem",this);
|
||||
mNumberPicker = (NumberPicker*)findViewById(w9::R::id::numpicker);
|
||||
mNumberPicker->setVisibility(View::GONE);
|
||||
mText1=(TextView*)findViewById(w9::R::id::text1);
|
||||
mText2=(TextView*)findViewById(w9::R::id::text2);
|
||||
mText1->setText(attr.getString("text1"));
|
||||
mText2->setText(attr.getString("text2"));
|
||||
LOGD("mNumberPicker=%p text=%p/%p",mNumberPicker,mText1,mText2);
|
||||
mNumberPicker->setOnValueChangedListener([this](NumberPicker&v,int ov,int nv){
|
||||
mText1->setText(std::to_string(nv));
|
||||
if(ov<mValues.size()&&ov>=0) ov=mValues.at(ov);
|
||||
if(nv<mValues.size()&&nv>=0) nv=mValues.at(nv);
|
||||
if(mOnValueChangedListener)
|
||||
mOnValueChangedListener(v,ov,nv);
|
||||
});
|
||||
}
|
||||
|
||||
NumberPicker&OptionPicker::getPicker(){
|
||||
return *mNumberPicker;
|
||||
}
|
||||
|
||||
void OptionPicker::setText(const std::string&text){
|
||||
mText1->setText(text);
|
||||
}
|
||||
|
||||
void OptionPicker::setText(const std::string&text1,const std::string&text2){
|
||||
mText1->setText(text1);
|
||||
mText2->setText(text2);
|
||||
}
|
||||
|
||||
void OptionPicker::setOnValueChangedListener(NumberPicker::OnValueChangeListener onValueChangedListener){
|
||||
mOnValueChangedListener=onValueChangedListener;
|
||||
}
|
||||
|
||||
void OptionPicker::setValuedName(const std::vector<int>&values,const std::vector<std::string>&names){
|
||||
mValues=values;
|
||||
mNumberPicker->setMinValue(0);
|
||||
mNumberPicker->setMaxValue(values.size());
|
||||
mNumberPicker->setDisplayedValues(names);
|
||||
}
|
||||
|
||||
void OptionPicker::showOptions(bool on){
|
||||
mNumberPicker->setVisibility(on?View::VISIBLE:View::GONE);
|
||||
LOGV("%p:%d visible=%d",this,mID,on);
|
||||
}
|
||||
|
||||
static int makeMeasureSpec(int measureSpec, int maxSize){
|
||||
if (maxSize == -1/*SIZE_UNSPECIFIED*/) {
|
||||
return measureSpec;
|
||||
}
|
||||
int size = MeasureSpec::getSize(measureSpec);
|
||||
int mode = MeasureSpec::getMode(measureSpec);
|
||||
switch (mode) {
|
||||
case MeasureSpec::EXACTLY: return measureSpec;
|
||||
case MeasureSpec::AT_MOST: return MeasureSpec::makeMeasureSpec(std::min(size, maxSize), MeasureSpec::EXACTLY);
|
||||
case MeasureSpec::UNSPECIFIED: return MeasureSpec::makeMeasureSpec(maxSize, MeasureSpec::EXACTLY);
|
||||
default: throw std::string("Unknown measure mode: ")+std::to_string(mode);
|
||||
}
|
||||
}
|
||||
|
||||
int OptionPicker::resolveSizeAndStateRespectingMinSize(int minSize, int measuredSize, int measureSpec) {
|
||||
if (minSize != -1/*SIZE_UNSPECIFIED*/) {
|
||||
int desiredWidth = std::max(minSize, measuredSize);
|
||||
return resolveSizeAndState(desiredWidth, measureSpec, 0);
|
||||
} else {
|
||||
return measuredSize;
|
||||
}
|
||||
}
|
||||
|
||||
void OptionPicker::onMeasure(int widthMeasureSpec, int heightMeasureSpec){
|
||||
RelativeLayout::onMeasure(widthMeasureSpec,heightMeasureSpec);
|
||||
return;
|
||||
// Try greedily to fit the max width and height.
|
||||
const int mMaxWidth=-1, mMaxHeight=-1;
|
||||
const int mMinWidth=-1, mMinHeight=-1;
|
||||
int newWidthMeasureSpec = makeMeasureSpec(widthMeasureSpec, mMaxWidth);
|
||||
int newHeightMeasureSpec = makeMeasureSpec(heightMeasureSpec, mMaxHeight);
|
||||
RelativeLayout::onMeasure(newWidthMeasureSpec, newHeightMeasureSpec);
|
||||
// Flag if we are measured with width or height less than the respective min.
|
||||
int widthSize = resolveSizeAndStateRespectingMinSize(mMinWidth, getMeasuredWidth(),
|
||||
widthMeasureSpec);
|
||||
int heightSize = resolveSizeAndStateRespectingMinSize(mMinHeight, getMeasuredHeight(),
|
||||
heightMeasureSpec);
|
||||
LOGD("%p:%d setMeasuredDimension(%x/%d,%x/%d)",this,mID,widthSize,widthSize,heightSize,heightSize);
|
||||
setMeasuredDimension(widthSize, heightSize);
|
||||
}
|
||||
|
||||
void OptionPicker::onLayout(bool changed, int left, int top, int width, int height){
|
||||
RelativeLayout::onLayout(changed,left,top,width,height);
|
||||
return ;
|
||||
const int inptTxtMsrdWdth = mText2->getMeasuredWidth();
|
||||
const int inptTxtMsrdHght = mText2->getMeasuredHeight();
|
||||
const int msrdWdth = getMeasuredWidth();
|
||||
const int msrdHght = getMeasuredHeight();
|
||||
mText2->layout(0, msrdHght-inptTxtMsrdHght, inptTxtMsrdWdth, inptTxtMsrdHght);
|
||||
mText1->layout(0,msrdHght-inptTxtMsrdHght*2,inptTxtMsrdWdth, inptTxtMsrdHght);
|
||||
LOGD("%p:%d textSize=(%d,%d) measuredsize=%dx%d",this,mID,inptTxtMsrdWdth,inptTxtMsrdHght,msrdWdth,msrdHght);
|
||||
mNumberPicker->layout(0,0,inptTxtMsrdWdth,msrdHght-inptTxtMsrdHght*2);
|
||||
}
|
27
apps/w9/optionpicker.h
Normal file
27
apps/w9/optionpicker.h
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include <widget/relativelayout.h>
|
||||
#include <widget/numberpicker.h>
|
||||
#include <widget/textview.h>
|
||||
|
||||
class OptionPicker:public RelativeLayout{
|
||||
protected:
|
||||
NumberPicker*mNumberPicker;
|
||||
TextView* mText1,*mText2;
|
||||
std::vector<int>mValues;
|
||||
NumberPicker::OnValueChangeListener mOnValueChangedListener;
|
||||
protected:
|
||||
int resolveSizeAndStateRespectingMinSize(int minSize, int measuredSize, int measureSpec);
|
||||
void onMeasure(int widthMeasureSpec, int heightMeasureSpec)override;
|
||||
void onLayout(bool changed, int left, int top, int width, int height)override;
|
||||
public:
|
||||
OptionPicker(int,int);
|
||||
OptionPicker(Context*,const AttributeSet&attr);
|
||||
NumberPicker&getPicker();
|
||||
void setText(const std::string&text);
|
||||
void setText(const std::string&,const std::string&);
|
||||
void setOnValueChangedListener(NumberPicker::OnValueChangeListener onValueChangedListener);
|
||||
/*values used for uart commandid,names used for display,values.size==names.size*/
|
||||
void setValuedName(const std::vector<int>&values,const std::vector<std::string>&names);
|
||||
void showOptions(bool on);
|
||||
};
|
||||
|
@ -1,47 +1,21 @@
|
||||
#include <washoptions.h>
|
||||
#include <cdroid.h>
|
||||
#include <R.h>
|
||||
#include <optionpicker.h>
|
||||
|
||||
WashOptionsWindow::WashOptionsWindow(int options):Window(0,0,1280,800){
|
||||
WashOptionsWindow::WashOptionsWindow(int options):Window(0,0,-1,-1){
|
||||
LayoutInflater::from(getContext())->inflate("@layout/options",this);
|
||||
NumberPicker*np=(NumberPicker*)findViewById(w9::R::id::options);
|
||||
np->setMinValue(0);
|
||||
np->setMaxValue(4);
|
||||
np->setSelector(5,-1);
|
||||
LinearLayout*ll=(LinearLayout*)findViewById(w9::R::id::optionsContainer);
|
||||
const char*labels[]={
|
||||
"Button0",
|
||||
"Button1",
|
||||
"Button2",
|
||||
"Button3",
|
||||
"Button4",
|
||||
"Button5"
|
||||
};
|
||||
const int count=sizeof(labels)/sizeof(labels[0]);
|
||||
for(int i=0;i<count;i++){
|
||||
ToggleButton*opt=new ToggleButton(100,100);
|
||||
ll->addView(opt,new LinearLayout::LayoutParams(-1,32,1.f/count)).setId(100+i).setClickable(true);
|
||||
opt->setText(labels[i]);
|
||||
opt->setBackgroundResource("@drawable/optionbackground");
|
||||
opt->setOnClickListener(std::bind(&WashOptionsWindow::onOptionClick,this,std::placeholders::_1));
|
||||
ViewGroup*vg=dynamic_cast<ViewGroup*>(getChildAt(0));
|
||||
for(int i=0;i<vg->getChildCount();i++){
|
||||
vg->getChildAt(i)->setOnClickListener(std::bind(&WashOptionsWindow::onOptionClick,this,std::placeholders::_1));
|
||||
}
|
||||
dynamic_cast<FrameLayout::LayoutParams*>(np->getLayoutParams())->setMarginStart(600);
|
||||
FrameLayout*frame=(FrameLayout*)findViewById(w9::R::id::content);
|
||||
frame->requestLayout();
|
||||
}
|
||||
|
||||
void WashOptionsWindow::onOptionClick(View&v){
|
||||
ViewGroup*parent=v.getParent();
|
||||
const int count=parent->getChildCount();
|
||||
const bool checked=dynamic_cast<ToggleButton&>(v).isChecked();
|
||||
for(int i=0;i<count;i++){
|
||||
View*v=parent->getChildAt(i);
|
||||
dynamic_cast<ToggleButton*>(v)->setChecked(false);
|
||||
ViewGroup*vg=v.getParent();
|
||||
for(int i=0;i<vg->getChildCount();i++){
|
||||
OptionPicker*op=dynamic_cast<OptionPicker*>(vg->getChildAt(i));
|
||||
op->showOptions(op==&v);
|
||||
}
|
||||
dynamic_cast<ToggleButton&>(v).setChecked(checked);
|
||||
NumberPicker*np=(NumberPicker*)findViewById(w9::R::id::options);
|
||||
dynamic_cast<FrameLayout::LayoutParams*>(np->getLayoutParams())->setMarginStart(v.getLeft());
|
||||
FrameLayout*frame=(FrameLayout*)findViewById(w9::R::id::content);
|
||||
LOGD("set numberpicker to %d",v.getLeft());
|
||||
frame->requestLayout();
|
||||
invalidate();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user