1

Android에 익숙하지 않고 간단한 더미 응용 프로그램을 작성하여 자신의보기 클래스를 만드는 등의 작업을 배우려고합니다. 내가 왜 이러는거야? 액션 바의 버튼을 눌러서 탐색 할 수있는 여러 페이지로 구성된 UI를 원했습니다. 이제 터치 제스처를 통해 탐색하는 기능을 추가하려고했습니다. 그런 다음 원래 응용 프로그램과 똑같은 간단한 응용 프로그램으로 해결하려고하는 문제에 직면했습니다. 조금 더 간단합니다. 교체시 작업이 파손됩니다. 조각

() 문제

: 조각은 당신이 그들을 클릭하면, 터치 제스처를 먹는 한쪽에있는 ScrollView를해야합니까.

나는 이것에 대해 읽고 나는 내 자신의 FrameLayout을 만들고 @Override onInterceptTouchEvent 및 onTouchEvent 메서드를 만들어야 할 것이라고 알았다. 이제이 새로운 FrameLayout을 제 조각 컨테이너로 사용합니다. 그러나 LinearLayout 대신 FragmentLayout에서 ScrollView를 사용하여 응용 프로그램을 테스트 할 때 (이 코드 샘플에서와 같이) 여전히 제대로 작동하지 않습니다. 그러나이 시점에서 이것이 가장 큰 문제는 아니며, 내가 원하는대로 두 가지 방법으로 작업을 수행하면됩니다.

이 시점에서 조각이 터치 제스처를 통해 바뀌면 내 앱이 다운됩니다 ... 버튼은 여전히 ​​작동합니다. (자바)이 내 DummyFragmentSimpleView입니다

public class MainActivity extends Activity { 

    int pos; 

    TouchInterceptingLayout mtil; 

    CharSequence mTitle; 
    String[] mTitles; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     mtil = (TouchInterceptingLayout) findViewById(R.id.fragment_container); 

     pos = 0; 
     mTitle = getTitle(); 
     mTitles = getResources().getStringArray(R.array.dummy_seiten); 

     if(savedInstanceState == null){ 
      switchFragment(0); 
     } 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu){ 
     MenuInflater inflater = getMenuInflater(); 
     inflater.inflate(R.menu.main, menu); 
     return super.onCreateOptionsMenu(menu); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item){ 

     switch(item.getItemId()){ 
     case R.id.action_nav_back: 
      navBackwards(); 
      break; 
     case R.id.action_nav_forward: 
      navForward(); 
      break; 
     } 

     return super.onOptionsItemSelected(item); 
    } 

    public void setTitle(CharSequence title){ 
     mTitle = title; 
     getActionBar().setTitle(mTitle); 
    } 

    public void navForward(){ 
     if(pos == 2){ 
      pos = 0; 
      switchFragment(pos); 
     } else { 
      pos += 1; 
      switchFragment(pos); 
     } 
    } 

    public void navBackwards(){ 
     if(pos == 0){ 
      pos = 2; 
      switchFragment(pos); 
     } else { 
      pos -= 1; 
      switchFragment(pos); 
     } 
    } 

    public void switchFragment(int position){ 
     Fragment newFrag; 
     Bundle args = new Bundle(); 
     args.putInt(DummyFragmentSimpleView.ARG_POSITION, position); 
     newFrag = new DummyFragmentSimpleView(); 
     newFrag.setArguments(args); 
     android.app.FragmentManager fm = getFragmentManager(); 
     FragmentTransaction ft = fm.beginTransaction(); 
     ft.replace(R.id.fragment_container, newFrag); 
     ft.commit(); 
    } 
} 

:

06-18 14:34:03.295: W/dalvikvm(2983): threadid=1: thread exiting with uncaught exception (group=0x409f51f8) 
06-18 14:34:03.305: E/AndroidRuntime(2983): FATAL EXCEPTION: main 
06-18 14:34:03.305: E/AndroidRuntime(2983): java.lang.IllegalStateException: Activity has been destroyed 
06-18 14:34:03.305: E/AndroidRuntime(2983):  at android.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1280) 
06-18 14:34:03.305: E/AndroidRuntime(2983):  at android.app.BackStackRecord.commitInternal(BackStackRecord.java:541) 
06-18 14:34:03.305: E/AndroidRuntime(2983):  at android.app.BackStackRecord.commit(BackStackRecord.java:525) 
06-18 14:34:03.305: E/AndroidRuntime(2983):  at com.example.trysomething.MainActivity.switchFragment(MainActivity.java:97) 
06-18 14:34:03.305: E/AndroidRuntime(2983):  at com.example.trysomething.MainActivity.navForward(MainActivity.java:74) 

이 내 MainActivity된다

이 오류 (로그 캣)를 얻고

public class DummyFragmentSimpleView extends Fragment { 

public static String ARG_POSITION = "position"; 

Bundle args; 

String[] dummyStringArray; 
String[] nonsenseArray; 

LayoutParams params; 

public void onCreate(Bundle savedInstanceState){ 
    super.onCreate(savedInstanceState); 

    dummyStringArray = getResources().getStringArray(R.array.dummy_array); 
    nonsenseArray = getResources().getStringArray(R.array.nonsense_array); 
    params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); 
    args = getArguments(); 
} 

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ 

    View mySimpleFrag = inflater.inflate(R.layout.fragment_notscrolling, container, false); 

    ImageView image = (ImageView) mySimpleFrag.findViewById(R.id.image_container); 
    String bild = getResources().getStringArray(R.array.dummy_seiten)[args.getInt(ARG_POSITION)]; 
    int bildId = getResources().getIdentifier(bild.toLowerCase(Locale.getDefault()), "drawable", getActivity().getPackageName()); 
    ((ImageView) image).setImageResource(bildId); 

    LinearLayout dummyLayout = (LinearLayout) mySimpleFrag.findViewById(R.id.content_container); 

    TextView t = (TextView) mySimpleFrag.findViewById(R.id.nonsense_text); 
    t.setText(nonsenseArray[args.getInt(ARG_POSITION)]); 

    for(int i = 0; i < dummyStringArray.length; i++){ 
     TextView text = new TextView(getActivity()); 
     text.setText(dummyStringArray[i]); 
     text.setId(i); 
     text.setLayoutParams(params); 
     text.setTextSize(20); 
     ((LinearLayout) dummyLayout).addView(text);   
    } 

    getActivity().setTitle(bild); 

    return mySimpleFrag; 
} 
} 

이가이다 단순보기 용 XML :

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="horizontal" 
    android:baselineAligned="false"> 

    <LinearLayout 
     android:id="@+id/left_panel" 
     android:layout_weight="1" 
     android:layout_width="0dp" 
     android:layout_height="match_parent" 
     android:orientation="vertical" 
     android:background="#C00000" 
     android:gravity="center"> 

     <ImageView 
      android:id="@+id/image_container" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content"/> 

    </LinearLayout> 



     <LinearLayout 
      android:id="@+id/right_panel" 
      android:layout_weight="2" 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:orientation="vertical"> 

      <TextView 
       android:id="@+id/nonsense_text" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:textSize="30sp" 
       android:textStyle="bold"/> 

      <LinearLayout 
       android:id="@+id/content_container" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:orientation="vertical"/> 

     </LinearLayout> 



</LinearLayout> 

그리고 이것은 내 TouchInterceptingLayout 클래스입니다 :

public class TouchInterceptingLayout extends FrameLayout{ 

    boolean mIsNavigating = false; 

    MotionEventHandler handler = new MotionEventHandler(); 

    public TouchInterceptingLayout(Context context) { 
     super(context); 
    } 

    public TouchInterceptingLayout(Context context, AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 

    public TouchInterceptingLayout(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    @Override 
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 
     for(int i = 0; i < getChildCount(); i++){ 
      getChildAt(i).layout(left, top, right, bottom); 
     } 
    } 

    @Override 
    public boolean onInterceptTouchEvent(MotionEvent event){ 

     float x1 = 0; 
     float x2 = 0; 

     final int action = event.getAction(); 

     if(action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP){ 
      mIsNavigating = false; 
      return false; 
     } 

     switch (action){ 
     case MotionEvent.ACTION_DOWN: 
      x1 = event.getX(); 
      break; 
     case MotionEvent.ACTION_MOVE: 
      return false; 
     case MotionEvent.ACTION_UP: 
      x2 = event.getX(); 
      if(Math.abs(x2 - x1) > 150){ 
       mIsNavigating = true; 
       return true; 
      } else { 
       return false; 
      } 
     } 
     return false; 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event){ 
     switch(event.getAction()){ 
     case MotionEvent.ACTION_DOWN: 
      handler.setXOne(event.getX()); 
      return true; 

     case MotionEvent.ACTION_UP: 
      handler.setXTwo(event.getX()); 
      handler.setDelta(); 
      handler.performAction(); 
      break; 
     } 
     return super.onTouchEvent(event); 
    } 
} 

MotionEventHandler 클래스 :

public class MotionEventHandler { 

    static final int MIN_X_DISTANCE = 150; 
    public float x1 = 0; 
    public float x2 = 0; 
    public float deltaX = 0; 
    MainActivity myBoss = new MainActivity(); 

    public MotionEventHandler(){ 
    } 

    public void setXOne(float x){ 
     x1 = x; 
    } 

    public void setXTwo(float x){ 
     x2 = x; 
    } 

    public float getXOne(){ 
     return x1; 
    } 

    public float getXTwo(){ 
     return x2; 
    } 

    public void setDelta(){ 
     deltaX = x2 - x1; 
    } 

    public float getDelta(){ 
     return deltaX; 
    } 

    public boolean isPageBeingSwapped(){ 
     if (Math.abs(deltaX)<MIN_X_DISTANCE){ 
      return false; 
     } else { 
      return true; 
     } 
    } 

    public void performAction(){ 
     if(isPageBeingSwapped()){ 
      if(deltaX < 0){ 
       myBoss.navBackwards(); 
      } else { 
       myBoss.navForward(); 
      } 
     } 
    } 
} 

activity_main.xml :

<?xml version="1.0" encoding="utf-8"?> 
    <com.example.trysomething.TouchInterceptingLayout 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/fragment_container" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"/> 
누군가가 도움이 될 수 있습니다 희망

, 내 문제를 그 설명이 너무 혼란스럽지 않고 내 문제가 너무 바보가 아니며 ...;

미리 감사드립니다.

답변

0

당신의 문제는 바로 여기에 발생하여 MotionEventHandler

public class MotionEventHandler { 

    static final int MIN_X_DISTANCE = 150; 
    public float x1 = 0; 
    public float x2 = 0; 
    public float deltaX = 0; 

    // -- Right here -- 
    MainActivity myBoss = new MainActivity(); 

    // The rest of your code 
} 

그것은 당신의 MainActivity가 파괴 된 것으로 아니기 때문에 당신이 점점 오류가 약간 오해의 소지가있다. 이 문제는 을 사용중인 것이 화면에 표시되지 않는 것입니다. 거의 모든 경우에 해당 생성자를 호출하여 Activity을 인스턴스화하지 않으려 고합니다.


다행히도이 문제는 비교적 간단합니다.

public MotionEventHandler(MainActivity mainAct) { 
    myBoss = mainAct; 
} 

그리고 당신의

TouchInterceptingLayout는 생성자 내부의 핸들러를 인스턴스화해야합니다 귀하의 MotionEventHandler는 다음과 같은 MainActivity에 사용하는 생성자가 있어야합니다.

public class TouchInterceptingLayout extends FrameLayout{ 
    MotionEventHandler handler; 

    public TouchInterceptingLayout(Context context) { 
     super(context); 
     if(context instanceof MainActivity) { 
      handler = = new MotionEventHandler((MainActivity) context) 
     } 
     else { 
      // Not a valid context 
     } 
    } 
    public TouchInterceptingLayout(Context context, AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 

    public TouchInterceptingLayout(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     if(context instanceof MainActivity) { 
      handler = = new MotionEventHandler((MainActivity) context) 
     } 
     else { 
      // Not a valid context 
     } 
    } 

    // The rest of your code 
} 
+0

당신, 선생님. :) 고마워요. – walkslowly

관련 문제