안 드 로 이 드 다단 계 연동 컨트롤 실현 사고 토론
그래서 다단 계 연동 선택 컨트롤 이 필요 합 니 다.인터넷 에서 검색 하거나 이 컨트롤 을 찾 았 습 니 다.Android-PickerView
이 컨트롤 은 3 급 이내 의 연동 에는 문제 가 없 지만 최대 3 급 까지 만 가능 하 다.
나 는 원래 의 기초 위 에서 약간의 확장 을 했 는데,주로 두 개의 picker 를 추가 했다
MultiWheelPickerView 는 데이터 동적 에 따라 여러 개의 롤러 를 생 성 할 수 있 으 며 두 개의 세 가지 옵션 에 국한 되 지 않 습 니 다.Dynamic WheelPickerView 도 동적 으로 생 성 되 지만 한 단계 한 단계 데 이 터 를 불 러 오고 롤러 를 추가 할 수 있 습 니 다.
사용 할 때 자신의 상황 에 따라 자바 빈 이 IWheel Item 이나 IDynamicWheel Item 을 실현 하도록 하면 됩 니 다.
제 생각 과 실현 을 기록 하고 공유 하 며 여러분 과 함께 더 좋 은 실현 방안 을 토론 하고 싶 습 니 다.
처음에는 얻 은 데이터 의 동태 적 인 생 성 롤러 에 따라 몇 단계 가 있 으 면 몇 개 를 생 성하 고 자동 으로 배열 하면 된다.
원본 코드 를 보 니 원래 의 Options PickerView 에 WheelView 세 개가 죽 었 기 때문에 최대 세 개 밖 에 안 된다.
WheelView 를 동적 으로 생 성 하려 면 죽 을 수 없고 데이터 에 따라 만 생 성 할 수 있 기 때문에 저 는 코드 를 사용 하여 WheelView 를 만 들 고 layot 레이아웃 의 고정 수량 을 사용 하지 않 습 니 다.
휠 뷰 부분 을 제외 한 나머지 부분 은 모두 원래 의 레이아웃 을 사용한다.
데 이 터 를 동적 으로 표시 하려 면 원래
IPickerViewData
를 사용 할 수 없 기 때문에 새로운IWheelItem
을 사 용 했 습 니 다.
public interface IWheelItem {
/**
*
* @return
*/
String getShowText();
/**
*
* @return
*/
<T extends IWheelItem> List<T> getNextItems();
}
두 가지 방법 만 있 습 니 다.롤러 에 표시 할 데 이 터 를 되 돌려 줍 니 다.1 단 계 를 선택 하면 다음 단계 의 내용 을 자동 으로 가 져 옵 니 다.이런 다단 계 연동 의 데 이 터 는 상하 관계 가 뚜렷 하 다.나 는 기본적으로 이런 구조 이 고 한 단계 에 한 단계 씩 연결 되 어 있다.
WheelView 에서 조정 을 했 어 요.
/**
*
*
* @param item data resource
* @return
*/
private String getContentText(Object item) {
if (item == null) {
return "";
} else if (item instanceof IPickerViewData) {
return ((IPickerViewData) item).getPickerViewText();
} else if (item instanceof Integer) {
// .
return getFixNum((int) item);
}else if (item instanceof IWheelItem){
return ((IWheelItem)item).getShowText();
}
return item.toString();
}
First of all,데이터 의 등급 을 확정 하고 등급 에 따라 WheelView 의 수량 을 생 성 합 니 다.
/**
* list ,
*
* @param list
* @return
*/
private int getLevel(List<T> list) {
int level = 0;
if (list != null && list.size() > 0) {
level = 1;
int childLevel = 0;
for (T code : list) {
List<T> children =code.getNextItems();
int temp = getLevel(children);
if (temp > childLevel) {
childLevel = temp;
}
}
level += childLevel;
}
return level;
}
저 는 LinearLayout 의 가로 배열 을 사용 하여 동적 으로 생 성 된 WheelView 를 탑재 합 니 다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<include
layout="@layout/include_pickerview_topbar"
android:layout_width="match_parent"
android:layout_height="@dimen/pickerview_topbar_height" />
<LinearLayout
android:id="@+id/ll_multi_picker"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:gravity="center"
android:minHeight="180dp"
android:orientation="horizontal">
</LinearLayout>
</LinearLayout>
주의:여기 서 문 제 는 롤러 가 많이 생 성 되면 붐 비 는 것 이다.몇 개의 롤러 를 생 성 해 야 하 는 지 알 게 된 후 코드 생 성 은 LinearLayout 에 직접 추 가 됩 니 다.
int level =getLevel(wheelItems);
if (level > 0) {
//
for (int i = 0; i < level; i++) {
WheelView wheelView = generateWheel();
mLlContainer.addView(wheelView);
}
// ,
initWheel(wheelItems, 0);
}
WheelView 를 생 성 한 후 컨트롤 에 값 을 부여 합 니 다.첫 번 째 값 을 선택 한 값 으로 기본 값 으로 가 져 옵 니 다.앞의 단계 가 선택 되면 다음 단계 의 데 이 터 를 가 져 와 다음 컨트롤 에 값 을 부여 합 니 다.이렇게 마지막 으로 돌아 갑 니 다.
protected void initWheel(List<T> list, int wheelIndex) {
WheelView wheelView = (WheelView) mLlContainer.getChildAt(wheelIndex);
if (null == wheelView) {
Log.d(MultiWheelPickerView.class.getSimpleName(), "initWheel: " + wheelIndex + " > " + mLlContainer.getChildCount());
return;
}
if (null != list && list.size() > 0) {
wheelView.setAdapter(new MultiWheelAdapter(list));
wheelView.setCurrentItem(0);
wheelView.setOnItemSelectedListener(new MultiWheelItemSelector(list, wheelIndex));
// , 。
T wheelItem = list.get(0);
addToResult(wheelItem, wheelIndex);
List<T> children = list.get(0).getNextItems();
// ,
wheelIndex++;
initWheel(children, wheelIndex);
}else{
for (int i=wheelIndex;i<mLlContainer.getChildCount();i++){
wheelView = (WheelView) mLlContainer.getChildAt(i);
wheelView.setAdapter(new MultiWheelAdapter(null));
}
}
}
선택 한 데이터 와 이벤트 에 대해 서 는 원래 와 마찬가지 로 하나의 형식 만 바 꾸 고 List 용 기 를 사용 합 니 다.순서대로 선택 한 데 이 터 를 모두 안에 열거 하 였 습 니 다.논 리 는 다음 과 같 습 니 다.
protected void addToResult(T value, int index) {
// ,
int size = resultList.size();
Log.d(MultiWheelPickerView.class.getSimpleName(), "addToResult: " + index + "-->" + value + "; size->" + size);
// ,
while (index < size) {
resultList.remove(index);
size = resultList.size();
}
// ,
boolean isAddToResult =true;
if (null!=listener){
// , , all, “”
isAddToResult = listener.isAddToResult(value);
}
if (isAddToResult) {
resultList.add(value);
}
if (null!=listener){
listener.onChange(resultList);
}
}
이렇게 조금 만 고치 면 동적 다단 계 관련 컨트롤 이 있 습 니 다.사용 할 때 자바 빈 이 IWheel Item 을 실현 하도록 하면 됩 니 다.간단 한 사용 방식 은 다음 과 같다.
MultiWheelPickerView<CodeTable> fixedPickerView;
private void fixedPicker() {
if (null == fixedPickerView) {
MultiWheelPickerBuilder<CodeTable> builder = new MultiWheelPickerBuilder<>(this,
new MultiWheelSelectListener<CodeTable>() {
@Override
public void onChange(List<CodeTable> result) {
//
showChange(result);
}
@Override
public void onSelect(List<CodeTable> result) {
//
StringBuffer buffer = new StringBuffer();
int size = result.size();
for (int i = 0; i < size; i++) {
if (i != 0) {
buffer.append("->");
}
buffer.append(result.get(i).getShowText());
}
mTvResult.setText(buffer.toString());
}
@Override
public boolean isAddToResult(CodeTable selectValue) {
//
return !selectValue.getCode().equalsIgnoreCase("all");
}
});
fixedPickerView = builder.build();
fixedPickerView.setTitleText(" ");
fixedPickerView.setWheelItems(getPickerData());
}
fixedPickerView.show();
}
다단 계 연동 을 실 현 했 지만 실제 사용 할 때 무시 할 수 없 는 문 제 를 발견 했다.데이터 가 너무 많 으 면 장시간 불 러 올 것 이다.성급 에서 마을 급 까지 수만 개의 기록 이 있 고 한 번 에 얻 으 면 체험 이 너무 나 쁘 고 무 너 질 위험 이 있다.더 좋 은 방법 은 1 급 1 급 으로 데 이 터 를 얻 는 것 이다.성급 을 선택 한 다음 에 부하 직원 의 시 급 을 얻 고 롤러 디 스 플레이 를 추가 하 는 것 이다.시 급 을 선택 한 다음 에 현급 을 얻 는 것 이다.이런 유추 이다.
So,계속 변경.데이터 도 여러 번 얻 었 기 때문에 등급 을 정할 수 없 기 때문에 새로운 등급 이 있 을 때마다 새로운 WheelView 를 디 스 플레이 용기 에 추가 해 야 합 니 다.
데 이 터 를 선택 할 때 도 다음 단 계 를 불 러 올 필요 가 있 는 지 판단 해 야 한다.나의 수요 에서 어떤 것 은 마을 급 에 가 야 하고 어떤 것 은 현급 에 가 야 한다.
그래서 다음 단계 의 설정 을 불 러 올 지 여 부 는 데이터 인터페이스 에 놓 고 데이터 자체 가 판단 합 니 다.
IWheel Item 을 바탕 으로 IDynamic Wheel Item 을 확장 하 였 습 니 다.
public interface IDynamicWheelItem extends IWheelItem {
/**
* @return
*/
boolean isLoadNext() ;
}
그 다음 에 WheelView 를 생 성 하 는 데 수정 을 했 고 들 어 오 는 데이터 에 따라 생 성 되 었 습 니 다.기본 값 으로 첫 번 째 항목 을 선 택 했 습 니 다.선택 할 수 있다 면 하위 데 이 터 를 계속 생 성하 거나 불 러 옵 니 다.
protected void generateWheel(List<T> data) {
if (data != null && data.size() > 0) {
// wheel
WheelView wheelView = generateWheel();
wheelView.setAdapter(new ArrayWheelAdapter(data));
mLlContainer.addView(wheelView);
int level = mLlContainer.getChildCount() - 1;
wheelView.setOnItemSelectedListener(new DynamicWheelItemSelector(data, level));
T iWheelItem = data.get(0);
addToResult(iWheelItem, level);
if (canSelect(iWheelItem)) {
List<T> nextItems = iWheelItem.getNextItems();
if (null != nextItems && nextItems.size() > 0) {
generateWheel(nextItems);
} else {
if (iWheelItem.isLoadNext()) {
loadNext(iWheelItem, ++level);
}
}
}
}
}
데 이 터 를 선택 한 후 롤러 값 도 수정 되 었 습 니 다.다음 데 이 터 를 불 러 올 지,기 존 데 이 터 를 불 러 올 지 여 부 를 판단 하 는 경우후속 으로 데이터 가 없 는 경우 에 도 휠 뷰 를 제거 하지 않 았 다.데이터 가 없 으 면 제거 하고 좌우 로 뛰 는 상황 이 발생 합 니 다.
/**
* Wheel
*
* @param current
* @param nextLevel
*/
private void setupChildWheel(T current, int nextLevel) {
if (mLlContainer.getChildCount() == nextLevel) {
if (current.isLoadNext()) { // ,
loadNext(current, nextLevel);
}
return;
}
List<T> nextItems = current.getNextItems();
// wheel , , view, null
WheelView wheelView = (WheelView) mLlContainer.getChildAt(nextLevel);
if (null != nextItems && nextItems.size() > 0) {
//
// level ==count
if (wheelView == null) {
wheelView = generateWheel();
}
wheelView.setAdapter(new ArrayWheelAdapter(nextItems));
wheelView.setCurrentItem(0);
wheelView.setOnItemSelectedListener(new DynamicWheelItemSelector(nextItems, nextLevel));
T wheelItem = nextItems.get(0);
addToResult(wheelItem, nextLevel);
nextLevel++;
if (canSelect(wheelItem)) {
setupChildWheel(wheelItem, nextLevel);
}else{ // ,
for (int i = nextLevel; i < mLlContainer.getChildCount(); i++) {
wheelView = (WheelView) mLlContainer.getChildAt(i);
wheelView.setOnItemSelectedListener(null);
wheelView.setAdapter(new MultiWheelAdapter(null));
}
}
} else {
// 。
//
for (int i = nextLevel; i < mLlContainer.getChildCount(); i++) {
wheelView = (WheelView) mLlContainer.getChildAt(i);
wheelView.setOnItemSelectedListener(null);
wheelView.setAdapter(new MultiWheelAdapter(null));
}
// ,
if (canSelect(current)&¤t.isLoadNext()) {
loadNext(current, nextLevel);
}
}
}
데 이 터 를 불 러 오 는 데 성공 한 후,데 이 터 를 대응 하 는 롤러 에 추가 해 야 합 니 다
public void appendWheel(List<T> list, int level) {
WheelView wheelView = null;
if (level < mLlContainer.getChildCount()) {
wheelView = (WheelView) mLlContainer.getChildAt(level);
} else {
wheelView = generateWheel();
if (null != list && list.size() > 0)
mLlContainer.addView(wheelView);
}
if (null != list && list.size() > 0) {
wheelView.setAdapter(new MultiWheelAdapter(list));
wheelView.setCurrentItem(0);
T codeTable = list.get(0);
addToResult(codeTable,level);
wheelView.setOnItemSelectedListener(new DynamicWheelItemSelector(list, level));
if (canSelect(codeTable)) { // , 。
//
level++;
setupChildWheel(codeTable,level);
}
}
}
이로써 고 쳤 으 니 이전 것 보다 두 가지 방법 을 더 내 놓 아 라.디텍터 에 하급 자 를 불 러 오 는 방법 을 확장 했다.
public interface DynamicWheelSelectListener<T extends IDynamicWheelItem>extends MultiWheelSelectListener<T> {
/**
*
* @param item
* @param nextLevel
*/
void loadNextItems(T item, int nextLevel);
}
사용 방법 은 위의 MultiWheelPickerView 와 대동소이 합 니 다.
DynamicWheelPickerView<CodeTable> dynamicPickerView;
private void dynamicPicker() {
if (null == dynamicPickerView) {
dynamicPickerView =new DynamicWheelPickerBuilder<CodeTable>(this,new DynamicWheelSelectListener<CodeTable>() {
@Override
public void loadNextItems(CodeTable item, int nextLevel) {
// , isLoadNext false。
List<CodeTable> child = getChild(random());
item.setChildren(child);
item.setLoadNext(false);
// ,nextLevel 。
dynamicPickerView.appendWheel(child, nextLevel);
}
@Override
public void onChange(List<CodeTable> result) {
showChange(result);
}
@Override
public void onSelect(List<CodeTable> result) {
StringBuffer buffer = new StringBuffer();
int size = result.size();
for (int i = 0; i < size; i++) {
if (i != 0) {
buffer.append("->");
}
buffer.append(result.get(i).getShowText());
}
mTvResult.setText(buffer.toString());
}
@Override
public boolean isAddToResult(CodeTable selectValue) {
// 0
return !selectValue.getCode().equalsIgnoreCase("0");
}
})
.build();
dynamicPickerView.setTitleText(" ");
dynamicPickerView.setWheelItems(getChild(random()));
}
dynamicPickerView.show();
}
구체 적 인 용법 은 코드 를 볼 수 있 습 니 다.여기 있 습 니 다TestMultiWheelActivity다른 생각:
저의 실현 방식 은 바로 이 렇 습 니 다.여러분 과 더 좋 은 방식 을 토론 할 수 있 기 를 바 랍 니 다.
여기 서 안 드 로 이 드 다단 계 연동 컨트롤 의 실현 방향 에 대한 토론 을 상세 하 게 설명 하 는 글 은 여기까지 입 니 다.더 많은 안 드 로 이 드 다단 계 연동 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 우 리 를 많이 지지 해 주세요!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.