Обратные звонки через Android - PullRequest
2 голосов
/ 26 мая 2020

Я новичок в Android и программировании в целом, и мне нужна небольшая помощь с обратными вызовами. Я понимаю суть обратных вызовов, но не знаю, как go реализовать.

Контекст: я пишу простое приложение для создания заметок, которое позволяет пользователю писать текст и сохранять его в приложении. Затем пользователь может запросить чтение файла с помощью кнопки. Затем текст отображается в текстовом окне основного действия. Существует возможность стереть этот файл, и это делается с помощью всплывающего окна подтверждения, что является еще одним действием. Это всплывающее окно содержит 2 кнопки: одну для отмены, а другую - для удаления. Если файл не пуст, он будет удален и ничего не сделает, если он пуст. Я не уверен, что это лучший способ реализовать его, но я хочу использовать кнопку очистки для обратного вызова основного действия, чтобы очистить текстовое представление. Я думал об использовании обратного вызова для отправки обратно логического значения. Основное действие будет проверять, истинно ли логическое значение, и очищать текстовое представление, если оно есть. Я не уверен, как реализовать обратный вызов в моем всплывающем окне, чтобы отправить это логическое значение обратно в основное действие.

Код для основного действия

public class MainActivity extends AppCompatActivity implements Popout.ClearTextView {

    Button bnRead,bnWrite,bnClear;
    TextView tvFileOP;
    EditText etInput;
    //    private static final String INPUT_CONTENT = "inputContent";
    public static final String  TV_CONTENT = "textViewContent";

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

        bnRead = (Button) findViewById(R.id.bnRead);
        bnWrite = (Button) findViewById(R.id.bnWrite);
        bnClear = (Button) findViewById(R.id.bnClear);

        tvFileOP = (TextView) findViewById(R.id.tvFileOP);
        etInput = (EditText) findViewById(R.id.etInput);
        tvFileOP.setMovementMethod(new ScrollingMovementMethod());

        final String fileName = "test_file";
        String data;

        bnRead.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                try {
                    FileInputStream fIn = openFileInput(fileName);
                    int c;
                    String temp = "";
                    while ( (c=fIn.read()) != -1){
                        temp = temp + Character.toString((char) c);
                    }
                    tvFileOP.setText(temp);
                    Toast.makeText(getBaseContext(),"file successfully read", Toast.LENGTH_LONG).show();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        bnWrite.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String data = etInput.getText().toString();
                try {
                    FileOutputStream fOut = openFileOutput(fileName,MODE_APPEND);
                    fOut.write(data.getBytes());
                    fOut.close();
                    etInput.setText("");
                    Toast.makeText(getBaseContext(),"file successfully written", Toast.LENGTH_LONG).show();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        bnClear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(MainActivity.this,Popout.class));
            }
        });

    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        outState.putString(TV_CONTENT,tvFileOP.getText().toString());
        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        tvFileOP.setText(savedInstanceState.getString(TV_CONTENT));
    }


    @Override
    public void clearTextView(Boolean clear) {
        if (clear){
            tvFileOP.setText("");
        }
    }
}

Код для всплывающего меню подтверждения

public class Popout extends AppCompatActivity {

    Button bnClosepopup,bnWipe;
    TextView tvConfirmation;
    String fileName = "test_file";
    TextView tvFileOP;

    public interface ClearTextView {
        public void clearTextView(Boolean clear);
    }

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

        bnClosepopup = (Button) findViewById(R.id.bnClosepopup);
        bnWipe = (Button) findViewById(R.id.bnWipe);
        tvConfirmation = (TextView) findViewById(R.id.tvConfirmation);


        //HIDING THE TOOL BAR AT THE TOP OF THE SCREEN
        this.getSupportActionBar().hide();

        //GETTING THE SIZE OF THE SCREEN
        DisplayMetrics displayMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        int height = displayMetrics.heightPixels;
        int width = displayMetrics.widthPixels;
        getWindow().setLayout((int) (width*0.8) , (int) (0.8*height));

        bnClosepopup.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        bnWipe.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    File dir = getFilesDir();
                    File file = new File(dir, fileName);
                    boolean deleted = file.delete();
                    Toast.makeText(getBaseContext(),"file has been deleted",Toast.LENGTH_SHORT).show();

                } catch (Exception e) {
                    Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_LONG).show();
                }
                finish();

            }
        });
    }
}

Я новичок в разработке android, и любые советы о том, как улучшить мой код, были бы очень признательны :)

Ответы [ 2 ]

1 голос
/ 26 мая 2020

В этом случае нет возможности передать интерфейс другому действию, потому что это действие для взаимодействия действий.

Вы должны использовать какой-то другой метод, есть несколько способов подойти, лучший способ, который я могу придумать, - использовать startActivityForResult() для запуска действия, а затем ждать ответа, чтобы вернуться, а затем запросить этот ответ в MainActivity, переопределив метод onActivityResult():

Пример

В MainActivity:

    //on click of this button
    bnClear.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            Intent intent = new Intent(MainActivity.this,Popout.class);
            int requestCode = 12; //it could be whatever you want
            startActivityForResult(intent , requestCode);

        }
    });


//override this method


@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

//this is triggered when you finish the Popout Activity
if(requestCode == 12 && resultCode == Activity.RESULT_OK){

// get the boolean data returned from the Popout Activity
boolean deleted = data.getBooleanExtra("deleted_state" , false); //false is default if no value exists

}


}

В активности Popout:

    bnWipe.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            try {
                File dir = getFilesDir();
                File file = new File(dir, fileName);
                boolean deleted = file.delete();

                //send the result to onActivtyResult() in MainActivity
                Intent result = new Intent();
                result.putExtra("deleted_state", deleted ); 
                setResult(Activity.RESULT_OK, result);

                Toast.makeText(getBaseContext(),"file has been deleted",Toast.LENGTH_SHORT).show();

            } catch (Exception e) {
                Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_LONG).show();
            }
            finish();

        }
    });

ОБНОВЛЕНИЕ:

Будет так:

// get the boolean data returned from the Popout Activity
boolean deleted = data.getBooleanExtra("deleted_state" , false);
    if (deleted){
        tvFileOP.setText("");
    }
..........
0 голосов
/ 26 мая 2020

Что делать, если вы правильно поняли вашу проблему: вы хотите управлять своим событием нажатия кнопки «Wipe» из своей активности. Вот решение, которое может вам помочь.

1: Сделайте переопределенный конструктор вашего диалогового класса.

2: Создайте один абстрактный метод в диалоговом классе. (скажем, onWipeButtonClick). Вам также необходимо сделать абстрактный класс диалогового окна.

3: Внутри Click Listener кнопки «Wipe» вызовите абстрактный метод onWipeButtonClick.

4: Создайте экземпляр диалога в основной деятельности где угодно. Компилятор выдаст вам ошибку, потому что вы не реализовали метод обратного вызова. реализуйте свой метод onWipeButtonClick и сделайте необходимое для очистки данных внутри метода.

public abstract class WipeDialog extends Dialog{

private Context context;

  public WipeDialog(Context context){
   this.context = context;
  }

 public abstract void onWipeButtonClick(boolean isTextEmpty); 

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

    <initialization>

    btnWipe.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            onWipeButtonClick(<YOUR_BOOLEAN_CHECK>);
        }
    });
 }
}

А теперь в Activity:

WipeDialog dialog = new WipeDialog(MainActivity.this) {
  @Override
  public void onWipeButtonClick(boolean isTextEmpty) {
      //Do Need full with respected to your requirement on click of button 'WIPE'
  }
};

Надеюсь, это поможет. Спасибо!

...