Je suis nouveau sur Android et j'essaie d'écrire une application Dummy simple pour apprendre quelque chose sur la création de propres classes View et ainsi de suite. Pourquoi je fais ça? Je voulais avoir une interface utilisateur qui se compose de plusieurs pages qui peuvent être parcourues en appuyant sur les boutons de la barre d'action. Je voulais maintenant ajouter la fonctionnalité de navigation via les gestes tactiles. J'ai ensuite fait face au problème que j'essayais de résoudre avec cette application fictive, qui fait la même chose que mon application originale, un peu plus simple.L'activité est en train d'être détruite en remplaçant Fragment
Le (ancien) problème: Les fragments ont un ScrollView d'un côté, qui mange le geste touche, lorsque vous cliquez dessus. Je lis à ce sujet et je devais créer mes propres FrameLayout et @Override les méthodes onInterceptTouchEvent et onTouchEvent. J'utilise maintenant ce nouveau FrameLayout comme mon conteneur de fragments. Pourtant, il ne fonctionne toujours pas correctement lorsque je teste l'application avec un ScrollView dans le FragmentLayout au lieu d'un LinearLayout (comme dans cet exemple de code). Mais à ce stade, ce n'est pas mon plus gros problème, je pense que je n'aurai qu'à travailler un peu sur les deux méthodes pour les faire fonctionner comme je veux.
A ce stade mon application se bloque lorsque les fragments sont échangés via des gestes tactiles ... Les boutons fonctionnent toujours.
Je reçois cette erreur (LogCat):
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)
Ceci est mon MainActivity:
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();
}
}
Ceci est mon DummyFragmentSimpleView (Java):
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;
}
}
C'est le XML pour la vue simple:
<?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>
Et voici ma classe 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);
}
}
classe 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"/>
J'espère que quelqu'un peut aider, et que mon problème la description n'est pas trop confuse, et mon problème pas trop bête ...; s
Merci d'avance!
Vous, monsieur, l'avez fait! :) Merci beaucoup! – walkslowly