【问题标题】:Pass Arraylist from Fragment to RecyclerAdapter (Android)将 Arraylist 从 Fragment 传递到 RecyclerAdapter (Android)
【发布时间】:2018-10-29 13:48:42
【问题描述】:

我的项目是这样设置的:

在 MainActivity 我有一个 viewpager 可以在 4 个片段之间切换:

  1. 片段,2。片段,3. 片段和 4. 片段。

我在 2.Fragment 内部进行以下操作:

  • 初始化 recyclerview 和适配器。
  • 运行 asynctask 以获取 json
  • 运行 onJobFinishListener 将数据从 asynctask 添加到 arraylist

我需要做的是把asList从2.Fragment里面传给recyclerAdapter,这样我在onBindViewHolder里面就可以设置title相对于2.Fragment里面arraylist中的字符串了。

片段 2.:

public class CardViewTabelFragment extends Fragment implements jsonAsynctask.DataTabelFragment {

private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;

RecyclerAdapter adapter2;

List<String> asList;

jsonAsynctask jsonasynctask;

public CardViewTabelFragment() {
    // Required empty public constructor
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate( R.layout.card_list, container, false );

    recyclerView = (RecyclerView) view.findViewById( R.id.recycler_view );

    adapter = new RecyclerAdapter( );

    recyclerView.setAdapter( adapter );

    final RecyclerView.LayoutManager layoutManager = new LinearLayoutManager( getActivity() );

    ((LinearLayoutManager) layoutManager).setOrientation( LinearLayoutManager.VERTICAL );

    recyclerView.setLayoutManager( layoutManager );

    return view;

}

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint( isVisibleToUser );

    if (isVisibleToUser) {
        jsonasynctask = new jsonAsynctask( this );
        jsonasynctask.execute();
    }
}

@Override
public void onJobFinishListener(List<String> allId) {

    asList = new ArrayList<String>( jsonasynctask.uniqueStrings );

    asList.add( 0, "ALLE SENSORER" );
    asList.add( "NÆSTE SENSORER" );

    System.out.println( "MEGET VIGTIGT DU KIGGER HER: " + asList );

    adapter2.addList(asList);
    adapter2.notifyDataSetChanged();

 }
}

回收器适配器:

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.RecyclerViewHolder> {

List<String> data = new ArrayList<String>();

public RecyclerAdapter( List<String> linkedDevice ) {

    this.data = linkedDevice;

}

@Override
public void onBindViewHolder(RecyclerViewHolder recyclerViewHolder, int position) {

    recyclerViewHolder.mTitle.setText( data.get( position ) );
    recyclerViewHolder.mBeskrivelse.setText( OurData.beskrivelse[position] );
    //recyclerViewHolder.mTitle.setText( OurData.title[position] );
    recyclerViewHolder.cardView.setCardBackgroundColor( Color.parseColor( OurData.colors[position] ) );

}

@Override
public int getItemCount() {
    return this.data.size();
}

这是例外:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.yusuf.cxweb, PID: 13337
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.get(ArrayList.java:437)

* JSON ASYNCTASK *

public class jsonAsynctask extends AsyncTask<Void, Void, Void> {

JSONObject deviceArray;
JSONArray json2;

String username = "xxx";
String password = "xxx";
String credentials = username + ":" + password;
String xxxURL = "https://" + credentials + "@xxx.com/fetch.php?";

String basicAuth, line, json_string, json, device;

String data = "";

List<String> asList;

LinkedHashSet<String> uniqueStrings = new LinkedHashSet<String>();

List<String> allDevice = new ArrayList<String>();

Gson gson;

HttpURLConnection connection;
BufferedReader bufferedReader;

URL url;

private DataTabelFragment dataTabelFragment;

public jsonAsynctask(jsonAsynctask.DataTabelFragment dataTabelFragment) {

    this.dataTabelFragment = dataTabelFragment;

}

public void inBackground() {

    try {

        url = new URL( xxxURL );

        connection = (HttpsURLConnection) url.openConnection();

        basicAuth = "Basic " + new String( encodeBase64URLSafeString( credentials.getBytes() ) );

        connection.setRequestProperty( "Authorization", basicAuth );
        connection.setRequestMethod( "GET" );
        connection.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded" );
        connection.setRequestProperty( "Content-Language", "en-US" );
        connection.setUseCaches( true );
        connection.setDoInput( true );
        connection.setDoOutput( true );
        connection.connect();

        InputStream stream = connection.getInputStream();

        bufferedReader = new BufferedReader( new InputStreamReader( stream ) );

        line = "";

        while (line != null) {
            line = bufferedReader.readLine();
            data = data + line;
        }

        json2 = new JSONArray( data );

        for (int i = 0; i < json2.length(); i++) {

            deviceArray = json2.getJSONObject( i );

            device = deviceArray.getString( "device" );

            uniqueStrings.add( device );

            allDevice.add( device );

        }

    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

private static String encodeBase64URLSafeString(byte[] binaryData) {

    return android.util.Base64.encodeToString( binaryData, android.util.Base64.URL_SAFE );

}

@Override
protected Void doInBackground(Void... voids) {

    inBackground();

    return null;
}

@Override
protected void onPostExecute(Void aVoid) {
    super.onPostExecute( aVoid );

    dataTabelFragment.onJobFinishListener( allDevice );

    gson = new Gson();

    json = gson.toJson( data );

    json_string = data;

}

public interface DataTabelFragment {

    void onJobFinishListener(List<String> allId);

}

【问题讨论】:

  • 您面临的具体问题是什么?这里有很多不相关的代码。
  • 我需要将arraylist asList从2.Fragment传递给recyclerAdapter
  • 这样当我在onBindViewHolder中设置mTitle.setText时,标题将设置在asList里面的字符串之后
  • 如果对您仍然没有任何意义,我会很乐意详细说明

标签: android android-fragments android-recyclerview


【解决方案1】:

在 Recycler Adapter 中添加一个接受新列表的方法

public void addList(List<String> linkedDevice){ this.linkedDevice = linkedDevice; notifyDataSetChanged(); }

还将 getItemCount() 覆盖为 -

@Override public int getItemCount() { return this.linkedDevice.size(); }

【讨论】:

  • 感谢您的回答!我已经更新了你的建议,但收到了一个例外。
  • 你能发布堆栈跟踪@Yas
【解决方案2】:

您正在使用一些静态数组来获取数据,这似乎是错误的。

您可以做的是将数据保存在适配器中并更改您的onBindViewHolder()(使用静态数据的适配器的其他方法也是如此):

List<String> data = new ArrayList<String>;

@Override
public void onBindViewHolder(RecyclerViewHolder recyclerViewHolder, int position) {
    recyclerViewHolder.mBeskrivelse.setText(data[position]);
}

@Override
public int getItemCount() {
    return data.size();
}

在片段中:

RecyclerAdapter adapter;

@Override
public void onJobFinishListener(List<String> allId) {

    asList = new ArrayList<String>( jsonasynctask.uniqueStrings );
    asList.add( 0, "ALLE SENSORER" );
    asList.add( "NÆSTE SENSORER" );

    System.out.println( "MEGET VIGTIGT DU KIGGER HER: " + asList );
    adapter.setData(asList);
    adapter.notifyDataSetChanged();
} 

【讨论】:

  • 感谢您的回答!我已更新您的建议,但收到了例外。我已经在我的线程中更新了我的代码
  • 我更改了代码以包含getItemCount() 函数。但是,您还应该确保替换适配器内对 OurData 的所有引用,因为它不再用于获取数据。
  • 非常感谢。我不知道我怎么没看到。赞赏
  • 嗨,Doron,我的 2. 片段在运行时变为空白。当我调试时,我发现我的 getItemCount = 0。我意识到该方法正在运行,当应用程序启动时,因此 json Asynctask 没有机会更新 getItemCount。你知道我能做什么吗?提前致谢!
猜你喜欢
  • 1970-01-01
  • 2017-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-10
  • 1970-01-01
  • 2016-07-16
  • 1970-01-01
相关资源
最近更新 更多