NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: Vstup textu v CanvasView

V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Jaroslav Zakouřil:27.11.2017 19:38

Ve třídě CanvasView se ve 3D prostoru vytvářejí z jednoduchých prvků složitější prostorové objekty, s nimiž se dá libovolně pohybovat. Zde potřebuji např. pomocí EditTextu zadat název souboru, pod nímž se vytvořený objekt uloží a později se zase načte.Zkusil jsem jednak první způsob:
Hlavní aktivita:

public class Activity_Pohyb extends Activity {

    private CanvasView customCanvas;

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

        customCanvas = (CanvasView) findViewById(R.id.signature_canvas);

    }
    public void ulozNazev(View v) {
        customCanvas.ulozNazev();
    }
}

Její layout:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFFFFF"
    android:orientation="vertical" >

    <com.javacodegeeks.androidcanvasexample.CanvasView
        android:id="@+id/signature_canvas"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="top"
        android:contentDescription="@string/app_name"
        android:textColor="#FFFFFF" />

    <EditText
        android:id="@+id/editText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal|center"
        android:ems="10"
        android:hint="Napiš název souboru"
        android:inputType="text"
        android:visibility="visible" />
</FrameLayout>

Třída CanvasView - tady jsem umístil prvek EditText, který má umožnit uživateli vložit text, který se použije buď při uložení nebo při načtení souboru:

public class CanvasView extends View {

    private EditText edText;

    public CanvasView(Context c, AttributeSet attrs) {
        super(c, attrs);
        context = c;

        //edText.findViewById(editText);//Tady to způsobí chybu !!!!!

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);
    }


   @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        edText = new EditText(context);
        edText.findViewById(editText);//Tady to chybu nedělá.

//Tady se všechno vykresluje
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
        //Tady se pomocí dotyků na určitých souřadnicích ovládá pohyb prvků a načítání a ukládání objektů
        if (x > 650)
            if ((y > 420)&&(y < 490)) {ulozNazev();}//Tady by se měl vložit název souboru.
         }

        public void ulozNazev() {
            nazevStavby = edText.getText().toString();//TOHLE ZPŮSOBÍ ZASTRAVENÍ APLIKACE!!!!!!!!!!!!!!
            Toast.makeText(context,"Název je "+nazevStavby, Toast.LENGTH_SHORT).show();
        }
    }
}

Ačkoliv kompilace proběhne OK, EditText je viditelný a lze do něj napsat název a všechno jinak funguje, když se aktivuje metoda ulozNazev, aplikace se zastaví s hláškou: "Unfortunately, Pohyb_Prvku has stoped."

A pak druhý způsob, a to v metodě odDraw(Canvas canvas) vytvořit EditText za běhu programu:

LinearLayout lL = new LinearLayout(context);
lL.setBackgroundColor(Color.LTGRAY);
EditText editTextView = new EditText(context);
editTextView.setBackgroundColor(Color.DKGRAY);
editTextView.setVisibility(View.VISIBLE);
editTextView.setTextColor(Color.WHITE);
editTextView.setHint("AHOJ");
editTextView.setGravity(Gravity.RIGHT);//Toto nemá žádný vliv na pozici.
lL.addView(editTextView);

lL.measure(canvas.getWidth(), canvas.getHeight());
lL.layout(0, 0, canvas.getWidth()/2-50, canvas.getHeight()/2+50);
// placing the edit text at specific co-ordinates:
canvas.translate(0, 0);//Když změní 0 na třeba 100, přesune se celý canvas i s prvky.
lL.draw(canvas);

LinearLayout i EditText se sice vytvoří, (abych je viděl, nastavil jsem BackgroundColor layoutu na LTGRAY, edittextu na DKGRAY a písma na WHITE), hint se vypíše, ale EditText, který se vytvořil v levém horním rohu nelze přesunout jinam, a především do něj nelze zapisovat.

Poraďte, prosím, nějaké řešení. Raději bych použil první způsob s EditTextem v XML souboru.

 
Odpovědět
27.11.2017 19:38
Avatar
Jaroslav Zakouřil:7.12.2017 17:09

Opakovaně prosím o nějakou radu. Zkoušel jsem to i na fóru stackoverflow.com, ale ani tam mi zatím nikdo neporadil. Sice jeden pokus o radu přišel, ale bohužel nepoužitelný. Snad se najde někdo tady v Česku, vždyť jsme národ programátorů ! Prosím ! Jinak se nehnu z místa.

 
Nahoru Odpovědět
7.12.2017 17:09
Avatar
Atrament
Člen IT Redactor Gang
Avatar
Odpovídá na Jaroslav Zakouřil
Atrament:8.12.2017 0:21

Nějak zvláštně tam inicializuješ to edText, měl bys ho IMHO inicializovat stejně jako ten customCanvas v Activity_Pohyb

//místo
edText.findViewById(editText); //které ti způsobuje chybu
// by tuším mělo být
edText = (EditText) findViewById(R.id.editText);
 
Nahoru Odpovědět
8.12.2017 0:21
Avatar
Jaroslav Zakouřil:9.12.2017 18:18

Díky za radu. Opravil jsem inicializaci podle ní. Chybu to sice nehlásí, ale aplikace se bohužel opět zastaví s hláškou: "Unfortunately, Pohyb_Prvku has stoped." na řádku:

Toast.makeText(context,"Název je "+edText.getText().toString(), Toast.LENGTH_SHORT).show();

Takže to zase nedokáže přečíst, co jsem zadal do EditTextu.

 
Nahoru Odpovědět
9.12.2017 18:18
Avatar
Atrament
Člen IT Redactor Gang
Avatar
Odpovídá na Jaroslav Zakouřil
Atrament:9.12.2017 20:20

Čím víc na to koukám, tím míň jistý si jsem, že chápu o co se snažíš :) Nejsou mi jasné tyto věci:

  • proč tu logiku ohledně názvu souboru máš v CanvasView, více smyslu by mi dávala v Activity_Pohyb a přidal bych prostě tlačítko, po jehož stisknutí by se uložil název souboru zadaný do EditTextu. Nebo možná ještě líp bych celou tu věc okolo názvu souboru řešil nějakým dialogem. (Bylo by tam tlačítko "Uprav jméno souboru", po stisknutí by se to zeptalo na název souboru, uživatel by jej zadal a stiskl Ok a bylo by to)
  • co se to děje v onTouchEvent metodě, odkud se berou ty x a y a co znamenají ta čísla
 
Nahoru Odpovědět
9.12.2017 20:20
Avatar
Odpovídá na Atrament
Jaroslav Zakouřil:13.12.2017 12:59

K Tým dotazům: nejdřív ten druhý - aplikace vznikla na základě tohoto příkladu: https://examples.javacodegeeks.com/…vas-example/
Proto je ovládání založeno na metodě onTouchEvent pomocí souřadnic x a y displeje.

A co se týče toho druhého - přesunul jsem zadání názvu do Activity_Pohyb, a to tak, že jsem inicializoval Button buttUloz, EditText eText a TextView tView a vytvořil metodu getNazev k načtení názvu z CanvasView.

    eText = (EditText) findViewById(R.id.editText);
    tView = (TextView) findViewById(R.id.textView);
    buttUloz = (Button) findViewById(R.id.bUloz);
}

public void ulozNazev(View v) {
    if (eText.getVisibility() == INVISIBLE) {
        eText.setVisibility(VISIBLE);
        buttUloz.setText("potvrď.");
    }
    else {
        eText.setVisibility(INVISIBLE);
        buttUloz.setText("ULOŽ");
        nazev = eText.getText().toString();
        tView.setText(nazev);
        customCanvas.ulozNazev();
    }
}

public String getNazev() {
    return nazev;
}

V CanvasView jsem vytvořil proměnnou mActivityPohyb třídy Activity_Pohyb,

private final Activity_Pohyb mActivityPohyb;

a v konstruktoru ji inicializoval

mActivityPohyb = new Activity_Pohyb();

abych se pomocí mMainActivity­.getNazev() dostal k názvu souboru zadanému v MainActivity.

Takže po dotyku na tlačítko "ULOŽ" se zobrazí EditText s výzvou "Napiš název a" popis tlačítka se změní na "potvrď". Když se napíše název souboru a stiskne tlačítko "potvrď", měl by se pak soubor uložit pod zadaným názvem. V textView tView se skutečně zobrazí zadaný název (pro kontrolu), ale jak mi napíše Toast v CanvasView, soubor se uloží pod názvem "null", což znamená, že název se do CanvasView nepřenesl. (Vlastní uložení pod zadaným názvem souboru není ještě napsané - zatím se jen marně pokouším dostat k tomu názvu.)

Abys to mohl případně sám vyzkoušet, posílám Ti v soukromé zprávě drasticky ořezanou aplikaci (bez vykreslování a ovládání prvků i bez ukládání a načítání souboru - to všechno teď dělám v CanvasView). Všechno co potřebuji je zadat název souboru a pod tímto názvem uložit soubor a pak zase zobrazit seznam uložených souborů, jeden zvolit a načíst ho.
Zkoušel jsem i intent, ale nepodařilo si mi to, napsalo to hlášku:"Non-static variable cannot be referenced from a static context" a dál už jsem nevěděl co s tím.

 
Nahoru Odpovědět
13.12.2017 12:59
Avatar
Atrament
Člen IT Redactor Gang
Avatar
Odpovídá na Jaroslav Zakouřil
Atrament:28.12.2017 13:49

Omluvám se za velmi pozdní odpověď, ale znáš to - Vánoce :) Vidím tam hned jeden velký problém a sice:

mActivityPohyb = new Activity_Pohyb();

tím přece vytvoříš úplně novou instanci třídy Activity_Pohyb, která nemá s tou původní nic společného. Takže nemůžeš čekat, že EditText v této nové instanci bude něco obsahovat.

Že ti tohle uniklo mne přivádí na myšlenku, že si nejsi ještě tak úplně jistý co se týče objektově orientovaného programování, takže bych ti poradil nejprve si to pořádně projít, <a href='https:/­/www.itnetwor­k.cz/java/oop'>mís­tní tutoriály</a> jsou velmi solidní a pak teprve se pouštět do psaní aplikace.

 
Nahoru Odpovědět
28.12.2017 13:49
Avatar
Odpovídá na Atrament
Jaroslav Zakouřil:30.1.2018 9:54

Ahoj Atramente,
pozdě, ale přece odepisuji. Tvůj podnět mne zaujal, i když přímo můj problém nevyřešil. I tak díky. Nakonec jsem to vyřešil úplně jinak. Vytvořil jsem si přímo ve třídě CanvasView jednak jednoduchou klávesnici pro zadávání názvu souboru k uložení, jednak scrollovací seznam pro výběr souboru k načtení. Funguje to perfektně.

 
Nahoru Odpovědět
30.1.2018 9:54
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 8 zpráv z 8.