Good day. I ask for help, as I read a lot of information, but I did not find the answer. And please do not kick hard, since I'm just a beginner)))

This is the task: to get the json-data from the remote service, put the data in the layout. There can be a lot of such data, therefore layout `s should be created dynamically.

At first I did this: I parsed the json array by loop. and in the loop I started creating dynamically markup with ами и textview strokes. where you put the information from the array. Everything would be nothing, though the code turned out cumbersome awful. And I didn’t understand how to write an onclick handler to open a new activity when clicking on the main layout and transfer data from this layout.

I read it from different sources and redid it differently. Created an additional markup file:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 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:layout_marginTop="100dp" android:background="@drawable/main_background" android:orientation="vertical"> <LinearLayout android:id="@+id/layout_info" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:background="@color/white" android:onClick="onLayoutClick" android:orientation="vertical"> <LinearLayout android:id="@+id/layout_data" android:layout_width="match_parent" android:layout_height="60dp" android:orientation="horizontal" android:paddingEnd="5dp" android:paddingStart="10dp" android:paddingTop="5dp" tools:ignore="RtlSymmetry"> <TextView android:id="@+id/separator" android:layout_width="match_parent" android:layout_height="40dp" android:layout_marginTop="10dp" android:layout_weight="1.9" android:background="@drawable/separator" android:gravity="center_vertical|center_horizontal" /> <LinearLayout android:id="@+id/type_customer_address" android:layout_width="match_parent" android:layout_height="60dp" android:layout_weight="0.5" android:orientation="vertical"> <TextView android:id="@+id/type" android:layout_width="match_parent" android:layout_height="20dp" android:paddingStart="10dp" android:textColor="@color/material_drawer_primary_text" /> <TextView android:id="@+id/customer" android:layout_width="match_parent" android:layout_height="20dp" android:paddingStart="10dp" android:textColor="@color/material_drawer_secondary_text" android:textSize="12sp" /> <TextView android:id="@+id/address" android:layout_width="match_parent" android:layout_height="20dp" android:paddingStart="10dp" android:textColor="@color/material_drawer_secondary_text" android:textSize="12sp" /> </LinearLayout> <LinearLayout android:id="@+id/numer_date" android:layout_width="match_parent" android:layout_height="60dp" android:layout_weight="1.5" android:orientation="vertical"> <TextView android:id="@+id/numer" android:layout_width="match_parent" android:layout_height="20dp" android:background="#00aa00" android:gravity="center_vertical|center_horizontal" android:textSize="8sp" tools:ignore="SmallSp" /> <TextView android:id="@+id/date" android:layout_width="match_parent" android:layout_height="40dp" android:background="#00aa00" android:gravity="center_vertical|center_horizontal" android:textSize="8sp" tools:ignore="SmallSp" /> </LinearLayout> </LinearLayout> <LinearLayout android:id="@+id/info_badges" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="10dp" android:gravity="center" android:orientation="horizontal" android:paddingEnd="5dp" tools:ignore="RtlSymmetry"> <TextView android:id="@+id/info" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="10dp" android:layout_weight="0.45" android:textColor="#000000" android:textSize="14sp" /> <LinearLayout android:id="@+id/badges" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="top" android:layout_weight="1.55" android:orientation="vertical"> <ImageView android:id="@+id/badges1" android:layout_width="match_parent" android:layout_height="wrap_content" android:contentDescription="@string/map_task" app:srcCompat="@android:drawable/ic_menu_mapmode" /> </LinearLayout> </LinearLayout> </LinearLayout> <View android:layout_width="wrap_content" android:layout_height="2dp" android:layout_marginBottom="10dp" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:background="@color/dropShadow" /> 

And in a cycle through the adapter I process the data and output it in the main activity:

 String url = "https://site.ru/task_user.php"; String json = "{\"user_id\":\""+mSettings.getString(APP_PREFERENCES_ID, "")+"\"}"; HttpPostGetActivity handler = new HttpPostGetActivity(); String result = ""; try { result = handler.execute(url, json).get(); } catch (Exception e) { e.printStackTrace(); } ListView listViewAd = findViewById(R.id.LayoutTextView); // Упаковываем данные ArrayList<HashMap<String, Object>> data = new ArrayList<>(); HashMap<String, Object> map; String[] resultParts = result.split("::"); for (String resultPart : resultParts) { try { JSONObject dataJsonObj = new JSONObject(resultPart); JSONObject taskData = dataJsonObj.getJSONObject("Data"); taskId = taskData.getString("id"); JSONObject taskDateObj = taskData.getJSONObject("date"); taskDate = taskDateObj.getString("todo"); JSONObject taskType = taskData.getJSONObject("type"); nameType = taskType.getString("name"); JSONObject taskCustomer = taskData.getJSONObject("customer"); taskCustomerId = taskCustomer.getString("id"); taskCustomerFullName = taskCustomer.getString("fullName"); JSONObject taskAddressObj = taskData.getJSONObject("address"); taskAddressText = taskAddressObj.getString("text"); taskAddressCity = taskAddressObj.getString("cityId"); taskDescription = taskData.getString("description"); } catch (JSONException e) { e.printStackTrace(); Toast.makeText(getApplicationContext(), resultPart, Toast.LENGTH_SHORT).show(); } map = new HashMap<>(); map.put("type", nameType); map.put("customer", taskCustomerFullName); map.put("address", taskAddressText); map.put("numer", taskId); map.put("date", taskDate); map.put("info", taskDescription); data.add(map); } // Массив имен атрибутов, из которых будут читаться данные String[] from = { "type", "customer", "address", "numer", "date", "info" }; // Массив идентификаторов компонентов, в которые будем вставлять данные int[] to = { R.id.type, R.id.customer, R.id.address, R.id.numer, R.id.date, R.id.info }; // создаем адаптер SimpleAdapter adapter = new SimpleAdapter(this, data, R.layout.layout_block, from, to); // Устанавливаем адаптер для списка listViewAd.setAdapter(adapter); 

Please tell me how to correctly register an onclick handler. That is, it turns out that several layouts are dynamically created. If you write onclick in the xml markup, it works the same way. Whatever layout you click on. How to determine by which particular layout you clicked and collect data from this layout to transfer to another activity.

  • if I understood everything correctly, then in the example that you gave, there is one specific button with its id. And if such buttons are dynamically formed several and it turns out that they all will have the same id? - Shotlandec

3 answers 3

Use RecyclerView to solve your problem. In .xml your ViewHolder (a) add a button and hang up the listener.

Create a MyInterface for your MyFragment / MyActivity , add a method to it, for example:

MyInterface:

 public interface MyInterface { void goToNextActivity(String data); } 

MyFragment:

 public class MyFragment implements MyInterface{ private MyAdapter adapter; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_my, container, false); ... adapter = new MyAdapter(someDate); adapter.setDelegateFragment(new WeakReference<>(this)); .. return v; } ... @Override public void goToNextActivity(String data) { //Ваш код на то что вы хотите сделать } ... } 

It will receive data from your ViewHolder (a) and do everything you tell it.

Create a delegate with the reference type WeakReference in the Adapter (e) and ViewHolder (e).

 private WeakReference<MyInterface> delegateFragment; public void setDelegateFragment (WeakReference<MyInterface> delegateFragment){ this.delegateFragment = delegateFragment; } 

After you pass your data in the adapter , set to the previously created delegat (y) in the adapter (e), and then from the adapter (a) set to the ViewHolder (y) in the onBindViewHolder(@NonNull MyViewHolder holder, int position) method onBindViewHolder(@NonNull MyViewHolder holder, int position)

     ListView listViewAd = findViewById(R.id.LayoutTextView); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) { // Тут имеем доступ к data[position] // Создаём интент, кладём в него нужные данные и стартуем другое активити } }); 
    • "Here we have access to data [position]" - please kindly in more detail. I'm trying to print for the test: Toast.makeText (MainActivity.this, position, Toast.LENGTH_LONG) .show (); But so far nothing has come of it. - Shotlandec
    • @Shotlandec, first set a breakpoint and make sure that this line is working. And notifications require a UI thread, so in onItemClick use runOnUiThread(new Runnable() { @Override public void run() { // Тут Toast.makeText... } }); - A. Shakhov
    • reaction zero: runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, position, Toast.LENGTH_LONG).show(); } }); - Shotlandec
    • @Shotlandec Is breakpoint caught on this line? - A. Shakhov
    • it comes to this line, but does not go any further: runOnUiThread(new Runnable() { - Shotlandec

    the question is solved simply.

    1. Immediately after installing the adapter:

      // Устанавливаем адаптер для списка listViewAd.setAdapter(adapter);

    Register the listener:

     `listViewAd.setOnItemClickListener (listener);` 
    1. In the same activity where the adapter is installed, we write:

      AdapterView.OnItemClickListener listener = new AdapterView.OnItemClickListener () {

       @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id){ ((TextView) view.findViewById(R.id.type)).getText(); //or do your stuff Toast.makeText(MainActivity.this, ((TextView) view.findViewById(R.id.type)).getText(), Toast.LENGTH_LONG).show(); }}; 

    Everything. And now you can get any data from the blocks. The only time that I was at the top, as you can see, was written onclick to layout. Here it should be removed. Will not work with him.

    I found the answer here: https://stackoverflow.com/questions/4461134/android-listview-adapter-onclicklistener-issue