ProgressBar가 Android에서 표시되는 동안 사용자 상호 작용을 비활성화하는 방법은 무엇입니까?


80

사용자 지정 ProgressBar를 사용하고 있습니다. 이제 작업이 진행되는 동안 진행률 표시 줄이 표시되지만 사용자는 여전히보기 및 컨트롤과 상호 작용할 수 있습니다. ProgressDialog가 표시되는 것처럼 전체보기에서 사용자 상호 작용을 비활성화하려면 어떻게해야합니까?

기본보기 위에 투명보기를 사용하고 해당보기에 진행률 표시 줄을 표시하고 작업이 완료되면 해당보기를 숨겨야합니까?

아니면 내 parentView의 ID를 가져 와서 비활성화 하시겠습니까? 그러나 그런 다음보기 / 활동 / 조각에 대화 상자가 나타날 때 발생하는 것과 같이 배경을 어둡게 할 수 없습니다. 권리?

진행률 표시 줄이 표시되는 동안 사용자의 상호 작용을 허용하지 않는 방법을 알고 싶습니다.

감사



4
@txteclipse 진행률 표시 줄을 사용자 정의하고 싶지 않습니다. 이미 수행했습니다. 그래서 내 질문은 중복되지 않습니다. 진행률 표시 줄이 표시되는 동안 사용자 상호 작용을 비활성화하고 싶습니다. ProgressDialog가 표시 될 때 사용자는 진행률 대화 상자를 닫지 않고 다른 UI 컨트롤과 상호 작용할 수 없습니다. 이제 내 질문이 그 질문과 어떻게 중복됩니까? 내 질문은 사용자 정의와 관련이 없습니다.
intellignt_idiot

1
대화 상자의 모든 기능을 원하면 대화 상자를 사용해야합니다. 예를 들어, 수용된 대답은 키보드 상호 작용을 차단하지 않습니다. 연결된 질문의 두 번째 답변은 ProgressDialog에서 사용자 정의 ProgressBar 리소스를 사용하는 방법을 보여줍니다. 이것이 당신의 필요를 충족시키지 못한다면, ProgressBar와 함께 사용자 정의 레이아웃 을 사용할 수 있습니다 .
그래프 이론

답변:


147

귀하의 질문 : ProgressBar가 Android에서 표시되는 동안 사용자 상호 작용을 비활성화하는 방법은 무엇입니까?

사용자 상호 작용을 비활성화하려면 다음 코드를 추가하면됩니다.

getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
                    WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);

사용자 상호 작용을 되돌리려면 다음 코드를 추가하면됩니다.

getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);

다음은 예입니다. 참고 : 사용자 상호 작용을 비활성화하거나 유지하는 방법을 보여주는 예제를 제공합니다.

XML에 진행률 표시 줄을 추가합니다.

<ProgressBar
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/progressBar"
    android:visibility="gone"/>

MainActivity에서 버튼을 누르면 진행률 표시 줄이 표시되고 사용자 상호 작용이 비활성화됩니다.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mImageView = (ImageView) findViewById(R.id.imageView);
    mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
    mImageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mProgressBar.setVisibility(View.VISIBLE);
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
                    WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
        }
    });
}

그리고 사용자가 backPressed하면 진행률 표시 줄을 다시 제거하면 사용자 상호 작용이 유지됩니다.

  @Override
public void onBackPressed() {
    super.onBackPressed();
    mProgressBar.setVisibility(View.GONE);
    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
}

비활성화 및 회색으로 표시된 디스플레이 기능을 추가하려면 부모를 채우는 선형 레이아웃을 xml 레이아웃 파일에 추가해야합니다. # B0000000하고는 그것의 배경을 설정 visibilty하는 방법에 대해 GONE. 그런 다음 프로그래밍 방식 visibility으로 VISIBLE.

이 도움을 바랍니다!


1
이 구현에 대해 흥미로운 점이 있습니다. 저는 극지 시계 용 웨어러블 앱을 개발 중이며이 솔루션으로 인해 몇 가지 문제가 발생했습니다. 사용자가 화면을 빠르게 터치 할 때마다 이러한 터치 후 작업이 솔루션을 사용하여 UI를 차단하는 경우 (여러 이벤트를 방지하기 위해) 어떤 이유로 Android가 내 앱 뒤에있는 앱이나 옵션을 여는 것을 발견했습니다. 좀 더 잘 설명하기 위해 내 앱이 순식간에 최소화하고 그 순간 화면에있는 모든 것을 터치 할 수있게합니다. 비슷한 경험을 한 사람이 있습니까?
Roger

13

.NET Framework에 루트 레이아웃을 추가하여이 문제를 해결했습니다 ProgressBar.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:clickable="true"
    android:gravity="center"
    android:visibility="gone"
    android:id="@+id/progress">
    <ProgressBar
        style="?android:attr/progressBarStyleLarge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:indeterminate="true"
        android:indeterminateTintMode="src_atop"
        android:indeterminateTint="@color/primary"/>
</LinearLayout>

루트 레이아웃을 클릭 가능하게 만들었습니다.

android:clickable="true"

참고 : 기본보기 RelativeLayout에서 루트로 사용하고 마지막 위치 (마지막 자식)의 루트 레이아웃 내부에 위에서 언급 한 코드를 추가했습니다.

도움이 되었기를 바랍니다!!


FrameLayout대신 a 대신 LinearLayout에이 대답은 완벽하고 작동합니다. 감사합니다 Nivar
루카스 P.

배경보기에 버튼이있을 때 작동합니까? 이 루트 레이아웃에서 더 높은 고도를 설정하지 않는 한 이들의 고도는 더 높아 보이며 (적어도 API 21 이상) 클릭 할 수 있습니다.
Ixx


3

문서 기본 메서드 progressbar.setCancelable (false) 사용


1
그러나 이것이 사용자 상호 작용에 어떤 영향을 미칠까요? ProgressBar가 표시되고 취소 가능이 false로 설정된 동안에도 EditText를 터치하거나 입력 할 수 있습니다.
intellignt_idiot

6
그리고 언제부터 진행률 표시 줄이 setCancelable (false) 속성을 갖기 시작 했습니까?
intellignt_idiot

U는 작업이 부모보기로 setenabled false를 실행하고 작업이 완료된 후 setenabled를 true로 설정할 때 옵션이 있습니다.
Ramesh sambu

3

투명한 배경으로 대화를 만듭니다. 문제 getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);는 앱이 백그라운드로 이동하고 돌아올 때 사용자가 UI 구성 요소와 상호 작용할 수있게되어 훨씬 더 많은 처리를 할 수 있다는 것입니다. 따라서 UI 차단을 위해 투명한 대화 상자를 만들고 숨기기 / 표시 시간을 설정하려면. 실행 가능한 스레드에서 수행하십시오. 그래서 해결책은

public class TransparentDialogHelper {

    private Dialog overlayDialog;

    @Inject
    public TransparentDialogHelper() {

    }

    public void showDialog(Context context) {
        if (AcmaUtility.isContextFinishing(context)) {
            return;
        }
        if (overlayDialog == null) {
            overlayDialog = new Dialog(context, android.R.style.Theme_Panel);
            overlayDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED);
        }
        overlayDialog.show();
    }

    public void hideDialog() {
        if (overlayDialog == null || AcmaUtility.isContextFinishing(overlayDialog.getContext())) {
            return;
        }
        overlayDialog.cancel();
    }
}

-------- Timer

Handler handler = new Handler();
handler.postDelayed( () -> {
    view.hideProgress();
}, 2000);

탁월한 솔루션, 프로세스에 대한 명시적인 제어를 유지합니다. 오, 그래, 그리고 욱신 거린다. UPVOTED :)
tony gil

1

부모 레이아웃을 상대 레이아웃으로 만들고 다음을 추가하십시오.

    <RelativeLayout ... >

    <other layout elements over which prog bar will appear>

<RelativeLayout android:id="@+id/rl_progress_bar"
                android:layout_width="match_parent" android:clickable="true"
                android:layout_height="match_parent" >
<ProgressBar android:id="@+id/pb"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_centerInParent="true"
             android:indeterminateOnly="true"
             style="@android:style/Widget.DeviceDefault.ProgressBar"
             android:theme="@style/AppTheme.MyProgressBar"
    />
</RelativeLayout>

UI에 플로팅 버튼이있는 경우 여전히 모든 포커스를 잡고 진행률 표시 줄이 표시 될 때 클릭 가능한 상태로 유지됩니다. 이 용도 : (프로그 바가 보일 때 & 프로그 바를 보이지 않거나 사라지게 할 때 다시 활성화)

fb.setEnabled(false);

1

수락 된 답변 을 연장하려면 (말장난 의도) :

kotlin을 사용할 때 확장 기능을 사용할 수 있습니다. 이렇게하면 UI를 차단 및 차단 해제하는 빠르고 멋진 방법이 있습니다.

fun AppCompatActivity.blockInput() {
    window.setFlags(
        WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
        WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
}

fun AppCompatActivity.unblockInput() {
    window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
}

fun AppCompatActivity.blockInputForTask(task: () -> Unit) {
    blockInput()
    task.invoke()
    unblockInput()
}

활동에서 차단 및 차단 해제 기능을 사용할 수 있습니다. 또한 토스트 등을 표시하는 것과 같은 더 많은 기능을 추가 할 수 있습니다.

사용자 정의보기 또는 다른보기에서 사용하는 경우 컨텍스트를 활동으로 캐스트하고 함수를 사용할 수 있습니다.

사용 blockInputForTask서라운드 작업 선형 간단하고로 blockInput하고 unblockInput그들이 다른 범위에서 필요할 때.

다음 blockInputForTask과 같이 사용할 수 있습니다 .

blockInputForTask { 
    // Your lines of code
    // Can be multiple lines
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.