Android의 컨텍스트에서 작업 가져오기
이 사람 때문에 곤란해요.
사용자 지정 레이아웃 클래스 내에서 활동 방법을 호출해야 합니다.이 경우의 문제점은 레이아웃 내에서 작업에 액세스하는 방법을 알 수 없다는 것입니다.
종단 뷰
public class ProfileView extends LinearLayout
{
TextView profileTitleTextView;
ImageView profileScreenImageButton;
boolean isEmpty;
ProfileData data;
String name;
public ProfileView(Context context, AttributeSet attrs, String name, final ProfileData profileData)
{
super(context, attrs);
......
......
}
//Heres where things get complicated
public void onClick(View v)
{
//Need to get the parent activity and call its method.
ProfileActivity x = (ProfileActivity) context;
x.activityMethod();
}
}
프로필 활동
public class ProfileActivityActivity extends Activity
{
//In here I am creating multiple ProfileViews and adding them to the activity dynamically.
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.profile_activity_main);
}
public void addProfilesToThisView()
{
ProfileData tempPd = new tempPd(.....)
Context actvitiyContext = this.getApplicationContext();
//Profile view needs context, null, name and a profileData
ProfileView pv = new ProfileView(actvitiyContext, null, temp, tempPd);
profileLayout.addView(pv);
}
}
위에서 보시는 것처럼 profileView를 프로그램적으로 인스턴스화하고 있습니다. 이와 함께 activityContext를 전달합니다. 2가지 질문:
- 프로필 보기에 올바른 컨텍스트를 전달하고 있습니까?
- 상황에 맞는 활동을 하려면 어떻게 해야 합니까?
에서.Activity
지나쳐요, this
Context
배치에 적합합니다.
ProfileView pv = new ProfileView(this, null, temp, tempPd);
에 될 것입니다.Context
레이아웃에서, 하지만 당신은 그것이 실제로 당신의 것이라는 것을 알 것입니다.Activity
필요한 것을 가질 수 있도록 캐스팅할 수 있습니다.
Activity activity = (Activity) context;
가 하는 데 한 것입니다.Context
.Activity
UI 내에서 조각 또는 사용자 정의 보기로 작동하는 경우.ContextWrapper를 재귀적으로 풀거나 실패할 경우 null을 반환합니다.
public Activity getActivity(Context context)
{
if (context == null)
{
return null;
}
else if (context instanceof ContextWrapper)
{
if (context instanceof Activity)
{
return (Activity) context;
}
else
{
return getActivity(((ContextWrapper) context).getBaseContext());
}
}
return null;
}
- 아니요.
- 그럴수는 없어요.
안드로이드에는 두 가지 다른 맥락이 있습니다.애플리케이션용(BIG)과 각 보기용(활동 컨텍스트라고 함)을 하나씩 사용합니다.
선형 배치는 보기이므로 활동 컨텍스트를 호출해야 합니다.활동에서 호출하려면 "이것"이라고 부르기만 하면 됩니다.너무 쉽죠?
사용할때
this.getApplicationContext();
애플리케이션을 설명하고 보기를 관리할 수 없는 BIG 컨텍스트를 호출합니다.
Android의 큰 문제는 컨텍스트가 사용자의 활동을 호출할 수 없다는 것입니다.누군가가 안드로이드 개발을 시작할 때 이것을 피하는 것은 대단한 일입니다.클래스를 코드화하는 더 나은 방법을 찾아야 합니다(또는 "Context context"를 "Activity Activity"로 대체하고 필요할 때 "Context"로 캐스트해야 합니다).
안부 전해요.
제 대답을 업데이트하기 위해서입니다. 쉬운 Activity context
A를 정의하는 것입니다.static
e에 인스턴스Activity
를 들면.
public class DummyActivity extends Activity
{
public static DummyActivity instance = null;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Do some operations here
}
@Override
public void onResume()
{
super.onResume();
instance = this;
}
@Override
public void onPause()
{
super.onPause();
instance = null;
}
}
당신의 에Task
,Dialog
,View
의 , 을 수 .Activity context
:
if (DummyActivity.instance != null)
{
// Do your operations with DummyActivity.instance
}
그리고 코틀린에서:
tailrec fun Context.activity(): Activity? = when {
this is Activity -> this
else -> (this as? ContextWrapper)?.baseContext?.activity()
}
사용자 정의 레이아웃 클래스(비활동 클래스) 내에서 활동 메서드를 호출할 경우.인터페이스를 사용하여 대리인을 만들어야 합니다.
테스트가 되지 않아 제대로 코딩했지만 원하는 것을 이룰 수 있는 방법을 전달합니다.
우선 create and interface
interface TaskCompleteListener<T> {
public void onProfileClicked(T result);
}
public class ProfileView extends LinearLayout
{
private TaskCompleteListener<String> callback;
TextView profileTitleTextView;
ImageView profileScreenImageButton;
boolean isEmpty;
ProfileData data;
String name;
public ProfileView(Context context, AttributeSet attrs, String name, final ProfileData profileData)
{
super(context, attrs);
......
......
}
public setCallBack( TaskCompleteListener<String> cb)
{
this.callback = cb;
}
//Heres where things get complicated
public void onClick(View v)
{
callback.onProfileClicked("Pass your result or any type");
}
}
이를 모든 활동에 적용합니다.
이렇게 부르세요.
ProfileView pv = new ProfileView(actvitiyContext, null, temp, tempPd);
pv.setCallBack(new TaskCompleteListener
{
public void onProfileClicked(String resultStringFromProfileView){}
});
컨텍스트는 응용프로그램, 서비스, 활동 등일 수 있습니다.
일반적으로 활동에서 보기의 컨텍스트는 활동 자체이므로 이 컨텍스트를 활동에 캐스팅할 수 있다고 생각할 수 있지만 이 경우 컨텍스트는 ContextTemeWrapper일 수도 있기 때문에 항상 수행할 수는 없습니다.
ContextThemeWrapper는 최근 버전의 AppCompat 및 Android(안드로이드: 레이아웃의 테마 속성 덕분에)에서 많이 사용되므로 개인적으로 이 캐스팅을 수행하지 않을 것입니다.
즉, 보기의 컨텍스트에서 작업을 안정적으로 검색할 수 없습니다.활동을 매개변수로 사용하는 메서드를 호출하여 보기에 활동을 전달합니다.
보기와 함께 getApplicationContext()를 사용하지 마십시오.
보기가 활동에 붙어 있기 때문에 항상 활동의 맥락이 되어야 합니다.또한 사용자 지정 테마 세트가 있을 수 있으며, 응용프로그램 컨텍스트를 사용할 경우 모든 테마가 손실됩니다.여기에서 다양한 버전의 컨텍스트에 대해 자세히 알아보십시오.
Kotlin 사용자의 경우 -
val activity = context as Activity
활동은 컨텍스트의 전문이므로 컨텍스트가 있는 경우 사용할 활동을 이미 알고 있으며 단순히 a를 c에 캐스팅할 수 있습니다. 여기서 a는 활동이고 c는 컨텍스트입니다.
Activity a = (Activity) c;
Convert Activity를 사용했습니다.
Activity activity = (Activity) context;
나는 이것을(를)
fun Context.findActivity(): Activity? = when (this) {
is Activity -> this
is ContextWrapper -> baseContext.findActivity()
else -> null
}
또는 이 항목:
fun Context.findActivity(): Activity {
var context = this
while (context is ContextWrapper) {
if (context is Activity) return context
context = context.baseContext
}
throw IllegalStateException("no activity")
}
이 방법은 도움이 될 것입니다..!
public Activity getActivityByContext(Context context){
if(context == null){
return null;
}
else if((context instanceof ContextWrapper) && (context instanceof Activity)){
return (Activity) context;
}
else if(context instanceof ContextWrapper){
return getActivity(((ContextWrapper) context).getBaseContext());
}
return null;
}
도움이 되었으면 좋겠습니다.메리코딩!
실시간 데이터 콜백은 어떨까요?
class ProfileView{
private val _profileViewClicked = MutableLiveData<ProfileView>()
val profileViewClicked: LiveData<ProfileView> = _profileViewClicked
}
class ProfileActivity{
override fun onCreateView(...){
profileViewClicked.observe(viewLifecycleOwner, Observer {
activityMethod()
})
}
}
확장 함수를 만듭니다.context.getActivity()와 같은 컨텍스트를 사용하여 이 확장 함수를 호출합니다.
fun Context.getActivity(): AppCompatActivity? {
var currentContext = this
while (currentContext is ContextWrapper) {
if (currentContext is AppCompatActivity) {
return currentContext
}
currentContext = currentContext.baseContext
}
return null
}
Theo 솔루션의 Kotlin 안드로이드 속기 확장 버전
private fun Context?.getParentActivity() : AppCompatActivity? = when {
this is ContextWrapper -> if (this is AppCompatActivity) this else this.baseContext.getParentActivity()
else -> null
}
위에서 설명한 용법
언급URL : https://stackoverflow.com/questions/9891360/getting-activity-from-context-in-android
'source' 카테고리의 다른 글
PowerShell의 어레이에 요소를 동적으로 추가하려면 어떻게 해야 합니까? (0) | 2023.10.09 |
---|---|
자바에서 pl/sql 함수를 호출하시겠습니까? (0) | 2023.10.09 |
MariaDB에서 동적 열 이름을 변경하려면 어떻게 해야 합니까? (0) | 2023.10.09 |
원격 세션에서 Powershell 로그오프 (0) | 2023.10.09 |
mysql 숫자가 쉼표로 구분된 목록에 있는지 확인합니다. (0) | 2023.10.09 |