순환되는 ScrollableView 만들기 : 질문있습니다.

안녕하세요

다시 질문의 있어 이렇게 작성하게 되었습니다.

순환되는 scrollableview 를 만들고 있습니다.

여기서 순환된다는 말은
------------------------ ex --------------------
시작 - view1 : view2(보여짐) : view3

if( =>> 오른쪽 )
결과 - view2 : view3(보여짐) : view1

if( <<= 왼쪽 )
결과 - view 3: view1(보여짐) : view2

문제점 :

  • setViews(views) 를 이용해 뷰를 교채하는 과정에서 깜빡임???
    화면이 깜빡 거리는 것을 관찰 할 수 있는데, 이를 개선하고 싶습니다.

따라서

Q. 전체 뷰를 교체 하는 것이 깜빡임 문제를 발생하는 것인가??

Q. 일부 뷰만 추가 및 제거 하는 방법을 사용하고 싶은데,

------------------------ ex --------------------
시작 - view1 : view2(보여짐) : view3

if( =>> 오른쪽 ){
실행 - view1 : view2 : view3(보여짐)
실행 - view1: view2 : view3(보여짐) : view1(추가)
실행 - view1(삭제) : view2 : view3(보여짐) : view1
결과 - view2 : view3(보여짐) : view1
}
if( <<= 왼쪽 ){
실행 - view 1(보여짐) : view2: view3
실행 - view3(추가) : view 1(보여짐) : view2: view3
실행 - view3 : view 1(보여짐) : view2 : view3(삭제)
결과 - view3 : view 1(보여짐) : view2
}

addview()를 이용하니 오른쪽으로만 뷰가 추가되는 것을 확인하였습니다…

왼쪽에 ?? 뷰를 추가 하는방법??

Q. 다른 개선 방안? 혹은 위젯?을 알고 계시나요??

추가로

Q. TabbedBar 는 IOS 에서만 지원하는것으로 알고있는데, 안드로이드에서는 어떻게 처리하시나요?

아래의 소스는 순환적인 scrollableview 테스트를 위해 작성한 내용입니다.

------------------------- index.xml ------------------------------------

<ScrollableView id=“scrollableView” height=“100” width=“100” showPagingControl=“true”

           미리 지정된 양식 사용은 4개의 띄어쓰기로 들여쓰세요.

View 1

View 2

View 3

--------------------------- index.js ---------------------------------------

$.scrollableView.setCurrentPage( 1 );

$.scrollableView.addEventListener(“scrollEnd”, function(e){

console.log(e.currentPage);

var view_array = e.source.getViews();

if(e.currentPage==0){

console.log(“view_array[2]”+view_array[2]);

var new_view = view_array[2];

var views = [new_view,view_array[0],view_array[1]] ;

$.scrollableView.setViews( views );

$.scrollableView.setCurrentPage( 1 );

}else if(e.currentPage==2){

var new_view = view_array[0];

var views = [view_array[1],view_array[2],new_view] ;

$.scrollableView.setViews( views );

$.scrollableView.setCurrentPage( 1 );

}

});

질문작성도 쉽지않네요, 죄송합니다… 소스는 어떻게 올려야할지 모르겠네요,

코드 삽입은 다음 글을 참고하세요.

Q1. 뷰를 교체하는 과정에서 깜빡인다는 것이 무엇인지 잘 모르겠네요.
간단한 영상 링크가 있으신가요? 있으면 공유해주시면 도움이 될수도 있을 것 같아요.

Q2. 일부뷰만 추가 제거 하는 방법 아래 코드 참고하세요. (왼쪽이든 오른쪽이든 뷰를 넣고싶은 index 순서만 바꿔주시면 됩니다. )

//view controller를 만드셔서 원하시는 페이지에 놓으실 수 있습니다.
var view1 = Alloy.createController("firstView").getView();
var view2 = Alloy.createController("secondView").getView();
var view3 = Alloy.createController("thirdView").getView();

$.scrollableView.applyProperties({
    views : [view2, view1, view3],
    currentPage : 1
});

//혹은 for loop을 이용하실수도 있겠지요? ex)
for(var i in views){
    var VIEW = Alloy.createController('view').getView();
    data.push(VIEW)
}
$.scrollableView.applyProperties({
    views : data,
    currentPage : 1
});
//사용하셨던 방법 처럼하시고 원하시는 뷰를 지우실때는 remove
//index 또는 자식뷰들의 property를 알고 싶으실때 .children을 사용하세요.(scrollableView의 모든 child뷰를 Array로 보여줍니다)

선택한 뷰를 지우는 예)
$.scrollableView.addEventListener("scrollEnd", function(e){
    if(e.currentPage == 0) {
          $.scrollableView.remove(view3);
    }
});

-Q3. 위젯은 사용해본적이 없네요.
-.Q4. 저는 뷰와 버튼으로 커스터마이즈 해서 사용합니다.

//xml

<View id="viewWapper" layout="horizontal">
    <Button id="btn1">button1</Button>
    <Button id="btn2">button1</Button>
    <Button id="btn3">button1</Button>
</View>
//js 예)
Alloy.Globals.pW = Alloy.Globals.pW || parseInt(Ti.Platform.displayCaps.platformWidth);

$.btn1.width = parseFloat(Alloy.Globals.pW / 3);
$.btn2.width = parseFloat(Alloy.Globals.pW / 3);
$.btn3.width = parseFloat(Alloy.Globals.pW / 3);

$.btn1.addEventListener('click', function(e){
    $.setFocus(1)
})
$.btn2.addEventListener('click', function(e){
    $.setFocus(2)
})
$.btn3.addEventListener('click', function(e){
    $.setFocus(3)
})

$.setFocus = function(number){
        $. btn1. backgroundColor = "black"
	$. btn2. backgroundColor = "black"
	$. btn3. backgroundColor = "black"

	if (number == 1) {
		$. btn1.backgroundColor = 'red';
	} else if (number == 2) {
		$. btn2. backgroundColor =  'red';
	} else if (number == 3) {
		$. btn3. backgroundColor =  'red';
	}
}

```
1개의 좋아요

안녕하세요 답글 감사합니다.

추가로 문의가 있어 이렇게 적게 되었습니다.

Q. 전체 뷰를 교체 하는 것이 깜빡임 문제를 발생하는 것인가??

  • 문제가 되는 실행 동영상 링크 부분입니다.


링크

  • 항상 깜빡?? 임 현상이 발생하는 것은 아니지만,

  • 8~10 초 구간에 화면이 깜빡?? 거리는 것을 관찰 할 수 있습니다.

  • 두번째 동영상 입니다.

  • 이미지로 scrollableView 를 사용하면, 좀더 자주 깜빡임 현상이 나타나는 것을 - 확인 할 수 있습니다.


링크

  • 2~5초 구간 에서 깜빡임 현상

Q. 일부 뷰만 추가 및 제거 하는 방법을 사용하고 싶은데,

  • 제가 작성했던

    var views = [new_view,view_array[0],view_array1] ;

    $.scrollableView.setViews( views );

    $.scrollableView.setCurrentPage( 1 );

  • 내용에서 알려주신 아래의 내용으로

    $.scrollableView.applyProperties({
    views : [view2, view1, view3],
    currentPage : 1
    });

으로 변경 적용하여도 동일하게 깜빡 거리는 현상이 나타나내요,

Q. TabbedBar 는 IOS 에서만 지원하는것으로 알고있는데, 안드로이드에서는 어떻게 처리하시나요?,

  • 알려주신 내용 많은 도움이 되었습니다. 감사합니다.

setviews 가 아닌 해당 viewd의 내부를 바꾸는 형태로 해보세요.

아래와 같이 하고 view1, view2, view3은 그대로 나두고 그 안의 내용을 remove add 하는 형태로 바꾸거나
각 내부의 view 구조가 같다면 해당 view들의 속성만 바꾸고 remove, add, setViews 등을 호출하지 않은 상태로 변경한다면 깜박임이 없을겁니다.

<Alloy>
    <Window id="win">
        <ScrollableView id="scrollableView" showPagingControl="true">
            <View id="view1" backgroundColor="#123">
               <Label>View 1</Label>
            </View>
            <View id="view2" backgroundColor="#246">
             <Label>View 2</Label>
             </View>
            <View id="view3" backgroundColor="#48b">
             <Label>View 3</Label>
             </View>
        </ScrollableView>
    </Window>
 </Alloy>

코드를 봐야 자세히 알겠지만 아마도 뷰를 지우고 생성하는 과정에 생기는 현상인 듯 합니다.
위에 yomybaby님이 말한대로 해보시고 만약 안된다면 코드를 나눠주실수 있으신지요. 코드가 있으면 제 컴퓨터에서도 테스트 해보고 방법을 찾아 볼 수 있을 것 같네요. :slight_smile:

titanium sdk : 3.5.1.GA

입니다.

현재 테스중인 프로젝트? 링크입니다.
소스 링크

index.js

// create imageView 

var image_temp1 = Titanium.UI.createImageView(
	{
	width: Titanium.UI.FILL,
	height: Titanium.UI.FILL,
	image:	"/img/sample/subpage1/video_pay.png",
});
var image_temp2 = Titanium.UI.createImageView(
	{
	width: Titanium.UI.FILL,
	height: Titanium.UI.FILL,
	image:	"/img/sample/subpage1/video_pay1.png",
	}
);
var image_temp3 = Titanium.UI.createImageView(
	{
	width: Titanium.UI.FILL,
	height: Titanium.UI.FILL,
	image:	"/img/sample/subpage1/video_pay2.png",
	}
);

// create ScrollableView and init param set
var imagesView = Titanium.UI.createScrollableView({
	id : "video_ex",
	width: Titanium.UI.FILL,
	height: Titanium.UI.FILL,
	// show secnd imgIiew
	currentPage : 1,
	views:[image_temp1,image_temp2,image_temp3]
});

// images click event
imagesView.addEventListener('click', function(e) {
	console.log(e);
});

// scrollend event
imagesView.addEventListener("scrollEnd",function(e){
	console.log(e.currentPage);
	//get views info array
	var view_array = e.source.getViews();
	if(e.currentPage==0){
		// left move 
		
		console.log("view_array[2]"+view_array[2]);
		
		var new_view = view_array[2]; 
		var views_array = [new_view,view_array[0],view_array[1]] ;
		imagesView.applyProperties({
			views : views_array,
			currentPage :1, 
		});
	}else if(e.currentPage==2){
		//right move
		
		var new_view = view_array[0]; 
		
		var views_array = [view_array[1],view_array[2],new_view] ;
		imagesView.applyProperties({
			views : views_array,
			currentPage :1, 
		});
	}
});
// insert scrollableView
$.video_play.add(imagesView);

// show secnd imgIiew
$.scrollableView.setCurrentPage( 1 );

// scrollend event
$.scrollableView.addEventListener("scrollEnd", function(e){
	console.log(e.currentPage);
	var view_array = e.source.getViews();
	if(e.currentPage==0){
		// left move
		console.log("view_array[2]"+view_array[2]);
		var new_view = view_array[2]; 
		var views = [new_view,view_array[0],view_array[1]] ;
		$.scrollableView.setViews( views );
		$.scrollableView.setCurrentPage( 1 );
	}else if(e.currentPage==2){
		// right move
		var new_view = view_array[0]; 
		var views = [view_array[1],view_array[2],new_view] ;
		$.scrollableView.setViews( views );
		$.scrollableView.setCurrentPage( 1 );
	}
	
});

$.index.open();

index.tss

".container" : {
	backgroundColor:"white",
	layout : "vertical"
}


"Label": {
	width: Ti.UI.SIZE,
	height: Ti.UI.SIZE,
	color: "#000"
}

"#label": {
	font: {
		fontSize: 12
	}
}
"#video_arry" : {
	width: Titanium.UI.FILL,
	height: "40%",
	top : 30,
	layout: "vertical"
}

index.xml

<Alloy>
	<Window class="container">
		<View id="video_arry" >
			<View id="video_play" >
				 <!-- <ImageView id="video_ex"></ImageView> -->
			</View>
			
		</View>
		
    	<View>
    		<ScrollableView id="scrollableView" height="135" width="240" showPagingControl="true" >
            <View id="view1"  backgroundColor="#123" >
				<Label color="white">View 1</Label>
			</View>
			<View id="view2"  backgroundColor="#246" >
				<Label for="view2" color="white" >View 2</Label>
			</View>
			<View id="view3"  backgroundColor="#48b" >
				<Label color="white">View 3</Label>
			</View>
	        </ScrollableView>
    	</View>
		        	
	        	
	</Window>
</Alloy>

내부 속성값 만 변경한다는 내용을 제가 재대로 이해한건지 모르겠지만…

아래와 같이 시도해 보았습니다…

배경색과 label 의 text 값을 속성만 변경하는 방법을 사용하였습니다.

끊김 현상이 조금은 덜해진것 같다고 느껴져서,

이미지를 이용하였는데,

여전하다는 끊긴다는 사실에, 좌절하고 있습니다. ㅜㅜ

Q. addView를 사용하면, 뷰리스트에 오른쪽??? 으로 추가되던데, 왼쪽에 추가하는?? 뷰 추가 방법은 없나요?

index.xml

		<ScrollableView id="scrollableView" height="135" width="240" showPagingControl="true" >
        <ImageView id="view0"  image="/img/sample/subpage1/video_pay.png" >
			<Label id="label0" color="white">View 1</Label>
		</ImageView>
		<ImageView id="view1"  image="/img/sample/subpage1/video_pay1.png" >
			<Label id="label1" color="white" >View 2</Label>
		</ImageView>
		<ImageView id="view2"  image="/img/sample/subpage1/video_pay2.png" >
			<Label id="label2" color="white">View 3</Label>
		</ImageView>
        </ScrollableView>

index.js

 // show secnd imgIiew
$.scrollableView.setCurrentPage( 1 );

// scrollend event
$.scrollableView.addEventListener("scrollEnd", function(e){
	// console.log(e);
	var view_array = e.source.getViews();
	
	if(e.currentPage==0){
		// left move
		console.log("view_array[2].image : "+view_array[2].image);
		var new_img0 = view_array[2].image;
		var new_img1 = view_array[0].image;
		var new_img2 = view_array[1].image;
		
		
		$.view0.applyProperties({
			image : new_img0
		});
		$.view1.applyProperties({
			image : new_img1
		});
		$.view2.applyProperties({
			image : new_img2
		});
		
		var new_label0 = $.label2.getText( );
		var new_label1 = $.label0.getText( );
		var new_label2 = $.label1.getText( );
		
		$.label0.applyProperties({
			text : new_label0
		});
		$.label1.applyProperties({
			text : new_label1
		});
		$.label2.applyProperties({
			text : new_label2
		});
		$.scrollableView.applyProperties({
			currentPage :1, 
		});
	}else if(e.currentPage==2){
		// right move
		var new_img0 = view_array[1].image;
		var new_img1 = view_array[2].image;
		var new_img2 = view_array[0].image;
		 
		$.view0.applyProperties({
			image : new_img0
		});
		$.view1.applyProperties({
			image : new_img1
		});
		$.view2.applyProperties({
			image : new_img2
		});

		
		var new_label0 = $.label1.getText( );
		var new_label1 = $.label2.getText( );
		var new_label2 = $.label0.getText( );
		
		$.label0.applyProperties({
			text : new_label0
		});
		$.label1.applyProperties({
			text : new_label1
		});
		$.label2.applyProperties({
			text : new_label2
		});		
		$.scrollableView.applyProperties({
			
			currentPage :1, 
		});
	}
	
});

저도 아래의 방법으로 테스트 해보았는데 세번째 뷰에서 첫번재 뷰로 넘어 가는 부분에서 살짝 깜빡임이 나타납니다. 그러나 두번째 뷰로 현재 뷰를 지정하면 깜빡임이 없는 것을 알 수 있었습니다 (예: $.scrollableView.currentPage = 1)

또한 뷰를 지우거나 생성하는 과정에서도 깜빡임이 나타나는 것을 알수가 있었네요.
세번째뷰에서 다시 첫번째뷰를 보여주지 않고 바로 전 단계 뷰를 보여주고 그 안에 속성을 계속해서 바꾼다면 가능합니다만 코드가 복잡해질 것 같네요.

//childView.js
var args = arguments[0] || {};

$.container.backgroundColor = args.color;
$.label.text = args.message;
$.img.image = args.img;

//childView.xml
<Alloy>
	<View class="container" id="container">
		<ImageView id="img" width="200dp" height="Ti.UI.SIZE"/>
		<Label id="label" color="white" zIndex="1"  />
	</View>
</Alloy>
//index.js
$.index.open();

function getViews() {

	for (var i in data) {
		var childView = Alloy.createController('childView', {
			color : data[i].color,
			message : data[i].message,
			img : data[i].img
		}).getView();

		$.scrollableView.addView(childView);
	}
}

getViews();

$.scrollableView.addEventListener('scrollend', function(e) {
	if (e.currentPage == 2) {
		$.scrollableView.currentPage = 0;
	}
});
//index.xml
<Alloy>
	<Window class="container">
		<View>
			<ScrollableView id="scrollableView" height="135" width="240" showPagingControl="true" ></ScrollableView>
		</View>
	</Window>
</Alloy>

아래의 링크는 제가 전에 살짝 테스트해보다 말았던 코드인데 scroll뷰를 사용한 순환되는 뷰입니다. 깜빡임은 없으나 애니메이션을 추가했던 것인데 원하시면 수정하셔서 사용하셔도 좋습니다.

Q. addView를 사용하면, 뷰리스트에 오른쪽??? 으로 추가되던데, 왼쪽에 추가하는?? 뷰 추가 방법은 없나요?

A. 스크롤러뷰의 views 안의 array 순서를 바꾸면 왼쪽으든 오른쪽이든 가능합니다만 뷰를 추가하는 방법보다는 뷰안의 속성을 바꾸는 것이 더 쉽고 가벼울 것 같네요.
참고. array 안의 순서를 바꾸는 예제

1개의 좋아요

감사합니다. 저만 안되는건 아니였다는 것에 힘을 내서 다시 도전해보고 있습니다.

깜박입 없이 잘 구현할 수 있습니다.^^ 설명을 글로 하기가 어려울것 같지만 해볼께요.
똑같은 페이지를 준비하고 scrollableView의 페이지를 바꾸면 깜박임이 없습니다.

순차적으로 설명해 보겠습니다.
3페이지를 갖고 있는 ScrollableView를 마치 무한 페이지 효과를 주려고 한다고
아래 설명에서 [ ] 안에 있는 페이지가 현재 화면에 보이는 페이지 입니다.

A[B]C

위에서 처럼 현재 페이지가 B가 보이는 상황에서 오른쪽에서 왼쪽으로 스와이프하면

AB[C]

C가 보이게 됩니다.
이때 아래와 같이 보이지 않는 페이지 0번과 1번의 내용을 바꿉니다.

BC[C]

그리고 페이지를 애니메이션 없이 이동시킵니다.

B[C]C

이렇게 하면 깜박임이 없습니다. 이렇게 이동시킨후 두번째 C를 D로 만들어 줍니다.

B[C]D

이런식으로 하면 3페이지 ScrollableView를 가지고 무한 효과를 줄 수 있습니다.

음, 뷰 교체?하는 단계를 더 작은 단위로 나누고, 같은 뷰로 이동하는 듯하게,
먼가 감이 잡히는거 같습니다. 감사합니다.

계속 한번에 하려고 해서 그랬나봐요,

설명을 바탕으로 내부 속성값,
이미지만 교체하는 방법으로 깜박거림을 없엘수 있었는데요,

//right move [0][1]['2'] ==> [1]['2'][0]
		
var view_array = e.source.getViews();

var new_img0 = view_array[1].image.toString();
var new_img1 = view_array[2].image.toString();
var new_img2 = view_array[0].image.toString();
		
//right move [1][2]['2']
image_temp0.applyProperties({
	image : new_img0,
});
image_temp1.applyProperties({
	image : new_img1,
});
		
//right move [1]['2'][2]
imagesView.applyProperties({
    	currentPage :1, 
});
		
//right move [1]['2'][0]
image_temp2.applyProperties({
	image : new_img2,
});

여기서 추가로 질문이있습니다…

Q. 기존의 뷰에 있는 속성값이 아닌 뷰 자체를 교체 할수 있나요?

// set scrollableView views
$.imagesView.views = [view_left, view_center, view_right];

문제가 되는 깜박임 현상을 발생시킨 뷰를 모두 교체하는 내용인데요,

이걸 각각의 단계로 쪼개면 , 뷰를 교체 하는 방법도 가능 할 것 같아 질문드려요,

1개의 좋아요

여기서의 핵심은 뷰를 교체하느냐 아니냐가 아니고 미리 똑같은걸 준비해두고 페이지를 이동시켜서 깜박임을 없애고 다 이동시킨후에 다시 순서가 맞도록 양옆을 준비하는 것입니다.
따라서 이것만 지키면 깜박임은 없습니다.

이 글의 첫 질문이 올라온지 벌써 한달이 넘었네요. 원하시는데로 잘 구현되길 바랍니다. :sunny:

그러게요,
먼가 알았다 싶었는데,

var viewarray = $.scroll_view.getViews();
				
// left move ['0'][0][1]
$.scroll_view.views[2] = viewarray[1];
$.scroll_view.views[1] = viewarray[0];
// left move [0]['0'][1]
$.scroll_view.setCurrentPage(1);
// left move [2]['0'][1]
$.scroll_view.views[0] = view_temp;

$.scroll_view.views[2] = viewarray[1]; 이거에서 막히네요,

Q. 뷰 교체하는 방법이, ㅠㅠ