【问题标题】:Referencing context from a Recycle View Adapter从 Recyclerview 适配器引用上下文
【发布时间】:2018-01-23 06:57:09
【问题描述】:

我创建了一个使用卡片的回收视图适配器。 在每张卡片中,我想动态地将文本视图添加到该卡片内的线性布局中。

但是,我无法让代码运行

这是 RV 适配器:

public class RVAdapter extends RecyclerView.Adapter<RVAdapter.EventViewHolder>{

    Context context;


    List<Events> events;
    Calculations calculations = new Calculations();
    RVAdapter(List<Events> events){
        this.events = events;
    }

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

    @Override
    public EventViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_view, viewGroup, false);
        EventViewHolder pvh = new EventViewHolder(v);
        return pvh;
    }
    @Override
    public void onBindViewHolder(EventViewHolder eventViewHolder, int i) {
        eventViewHolder.eventName.setText(events.get(i).getName());
        eventViewHolder.eventLocation.setText(events.get(i).getLocationName());
        eventViewHolder.eventDate.setText(calculations.UnixTimeConverter(events.get(i).getUnixTimeStamp())[0]);
        eventViewHolder.eventTime.setText(calculations.UnixTimeConverter(events.get(i).getUnixTimeStamp())[1]);

        //TODO(2):Change code to dynamically add textviews with the proper parameters to the LinearLayout;
        //eventViewHolder.eventParticipants.setText(calculations.ParticipantConcatenation(events.get(i).getParticipants()));
        for (String x: events.get(i).getParticipants()) {
            TextView tv=new TextView(context);
            LinearLayout.LayoutParams params=new LinearLayout.LayoutParams
                    (LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
            params.leftMargin=50;
            params.topMargin=i*50;
            tv.setText(x);
            tv.setTextSize((float) 20);
            tv.setPadding(20, 50, 20, 50);
            tv.setLayoutParams(params);
            eventViewHolder.eventParticipants.addView(tv) ;
        }
    }
    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }


    public static class EventViewHolder extends RecyclerView.ViewHolder {
        CardView cv;
        TextView eventName;
        TextView eventTime;
        TextView eventLocation;
        TextView eventDate;

        //TODO(1):Change the type of eventParticipants to Linear Layout;
        LinearLayout eventParticipants;


        EventViewHolder(View itemView) {
            super(itemView);
            cv = itemView.findViewById(R.id.CardViewItem);
            eventName = itemView.findViewById(R.id.event_name);
            eventTime = itemView.findViewById(R.id.event_time);
            eventDate = itemView.findViewById(R.id.event_date);
            eventLocation = itemView.findViewById(R.id.event_location);
            eventParticipants = itemView.findViewById(R.id.event_participants);

        }

    }

}

错误似乎出现在我实例化新 TextView 并传入 Context 的地方。 我尝试将“this”传递给它,但它会导致构建时间错误说:

Textview中的TextView(android.context.Context)不能应用到(...RVAdapter)

我也试过传递一个

MainActivity.this

,但这会导致构建时错误,提示“MainActivity.this 不是封闭类。”

如果我只是在上下文中传递,它会导致运行时 NullPointerException 错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
                                                                                    at android.view.ViewConfiguration.get(ViewConfiguration.java:359)
                                                                                    at android.view.View.<init>(View.java:3587)
                                                                                    at android.view.View.<init>(View.java:3682)
                                                                                    at android.widget.TextView.<init>(TextView.java:637)
                                                                                    at android.widget.TextView.<init>(TextView.java:632)
                                                                                    at android.widget.TextView.<init>(TextView.java:628)
                                                                                    at android.widget.TextView.<init>(TextView.java:624)
                                                                                    at com.example.android.gatheraround.RVAdapter.onBindViewHolder(RVAdapter.java:56)
                                                                                    at com.example.android.gatheraround.RVAdapter.onBindViewHolder(RVAdapter.java:24)
                                                                                    at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6400)
                                                                                    at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6433)
                                                                                    at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5377)
                                                                                    at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5640)
                                                                                    at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5482)
                                                                                    at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5478)
                                                                                    at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2215)
                                                                                    at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1542)
                                                                                    at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1502)
                                                                                    at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:595)
                                                                                    at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3625)
                                                                                    at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java:3067)
                                                                                    at android.view.View.measure(View.java:17547)
                                                                                    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
                                                                                    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
                                                                                    at android.widget.LinearLayout.measureHorizontal(LinearLayout.java:1083)
                                                                                    at android.widget.LinearLayout.onMeasure(LinearLayout.java:615)
                                                                                    at android.view.View.measure(View.java:17547)
                                                                                    at android.support.v4.widget.NestedScrollView.measureChildWithMargins(NestedScrollView.java:1417)
                                                                                    at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
                                                                                    at android.support.v4.widget.NestedScrollView.onMeasure(NestedScrollView.java:482)
                                                                                    at android.view.View.measure(View.java:17547)
                                                                                    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
                                                                                    at android.support.design.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:713)
                                                                                    at android.support.design.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:785)
                                                                                    at android.view.View.measure(View.java:17547)
                                                                                    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
                                                                                    at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
                                                                                    at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139)
                                                                                    at android.view.View.measure(View.java:17547)
                                                                                    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
                                                                                    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
                                                                                    at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
                                                                                    at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
                                                                                    at android.view.View.measure(View.java:17547)
                                                                                    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
                                                                                    at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
                                                                                    at android.view.View.measure(View.java:17547)
                                                                                    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
                                                                                    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
                                                                                    at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
                                                                                    at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
                                                                                    at android.view.View.measure(View.java:17547)
                                                                                    at android.view.ViewGroup.measureChildWithMarg
08-15 19:27:17.358 3080-3080/com.example.android.gatheraround I/Process: Sending signal. PID: 3080 SIG: 9

如果有帮助,这里是 Main Activity 和 Layouts 的代码:

public class MainActivity extends AppCompatActivity {

    Button eventListButton;
    private BottomSheetBehavior mBottomsheetbehvior;
    RecyclerView rv;
    LinearLayoutManager llm;
    Context context;
    public List<Events> events;

    @Override
    protected void onCreate(Bundle savedInstanceState) {


        events = new ArrayList<Events>();

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Find Button
        eventListButton = (Button) findViewById(R.id.eventlistbutton);

        //Find bottom sheet
        android.support.v4.widget.NestedScrollView bottomsheet =
                (android.support.v4.widget.NestedScrollView) findViewById(R.id.bottomsheet);

        //Add bottomsheet behavior to view
        mBottomsheetbehvior = BottomSheetBehavior.from(bottomsheet);
        mBottomsheetbehvior.setHideable(true);
        mBottomsheetbehvior.setPeekHeight(400);
        mBottomsheetbehvior.setState(BottomSheetBehavior.STATE_HIDDEN);
        eventListButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(mBottomsheetbehvior.getState() == BottomSheetBehavior.STATE_EXPANDED) {
                    mBottomsheetbehvior.setState(BottomSheetBehavior.STATE_COLLAPSED);
                    eventListButton.setText("Hide");
                }
                else if(mBottomsheetbehvior.getState() == BottomSheetBehavior.STATE_COLLAPSED) {
                    mBottomsheetbehvior.setState(BottomSheetBehavior.STATE_HIDDEN);
                    eventListButton.setText("Event List Button");
                }
                else if(mBottomsheetbehvior.getState() == BottomSheetBehavior.STATE_HIDDEN) {
                    mBottomsheetbehvior.setState(BottomSheetBehavior.STATE_EXPANDED);
                    eventListButton.setText("Peek");
                }
            }
        });

        //Bottomsheet callbacks
        mBottomsheetbehvior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
                if (newState == BottomSheetBehavior.STATE_EXPANDED) {
                    eventListButton.setText("Peek");
                }
                else if (newState == BottomSheetBehavior.STATE_COLLAPSED) {
                    eventListButton.setText("Hide");
                }
                else if (newState == BottomSheetBehavior.STATE_HIDDEN) {
                    eventListButton.setText("Event List Button");
                }
            }

            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {

            }
        });

        //Recyler View
        rv = (RecyclerView) findViewById(R.id.rv);
        rv.setHasFixedSize(true);

        llm = new LinearLayoutManager(context);

        String[] participants = {"Tamim","Chiharu","Azmain","Miyoshi"};

        events.add(new Events(1302719286,"U22 project",participants,new LatLng(37.652832,219.839478),"Saizeriya"));
        events.add(new Events(1502419296,"U22 project",participants,new LatLng(32.652832,19.839478),"Hiroo"));
        events.add(new Events(1901719266,"U22 project",participants,new LatLng(19.652832,39.839478),"Canada"));
        events.add(new Events(1204219286,"U22 project",participants,new LatLng(100.652832,13.839478),"Tokyo Monorail"));
        RVAdapter adapter = new RVAdapter(events);
        rv.setAdapter(adapter);
        rv.setLayoutManager(new LinearLayoutManager(context));
    }
}

主要活动

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/bgLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="0dp"
    android:paddingLeft="0dp"
    android:paddingRight="0dp"
    android:paddingTop="0dp"
    tools:context=".MainActivity">
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        >
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            >
                <Button
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_margin="8dp"
                    android:text="EventList Button"
                    android:id="@+id/eventlistbutton"
                    />

        </RelativeLayout>
    </ScrollView>

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/bottomsheet"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipToPadding="true"
        android:background="@color/recyclerview_background"
        app:layout_behavior="@string/bottom_sheet_behavior"
        >
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <android.support.v7.widget.RecyclerView
                android:layout_height="match_parent"
                android:layout_width="match_parent"
                android:id="@+id/rv"
                android:layout_marginLeft="@dimen/recyclerviewhorizontalpadding"
                android:layout_marginRight="@dimen/recyclerviewhorizontalpadding"
                >

            </android.support.v7.widget.RecyclerView>

        </LinearLayout>

    </android.support.v4.widget.NestedScrollView>

</android.support.design.widget.CoordinatorLayout>

还有 CardView:

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/CardViewItem"
    card_view:cardCornerRadius="@dimen/cardviewcorner"
    card_view:cardElevation="8dp"
    card_view:cardBackgroundColor="@color/cardbackground2"
    android:layout_marginTop="16dp"

    >
    <LinearLayout
        android:orientation="vertical" android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:background="@color/cardbackground"
            >
            <TextView
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="2"
                tools:text="Dick Museum Tour"
                android:textSize="18sp"
                android:padding="@dimen/cardmargin"
                android:textStyle="bold"
                android:textColor="@color/white"
                android:id="@+id/event_name"
                />
            <TextView
                android:layout_height="match_parent"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:textSize="18dp"
                android:padding="@dimen/cardmargin"
                android:textStyle="bold"
                android:textColor="@color/white"
                tools:text="8/24"
                android:textAlignment="viewEnd"
                android:id="@+id/event_date"
                />

        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="@dimen/card_view_height"
            android:background="@color/cardbackground2"
            android:orientation="vertical"
            >
            <TextView
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                tools:text="Time:"
                android:textColor="@color/white"
                android:textSize="18sp"
                android:gravity="center_vertical"
                android:paddingLeft="@dimen/cardmargin"
                android:id="@+id/event_time"
                />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                tools:text="Location:"
                android:textColor="@color/white"
                android:textSize="18sp"
                android:gravity="center_vertical"
                android:paddingLeft="@dimen/cardmargin"
                android:clickable="true"
                android:id="@+id/event_location"
                />
            <HorizontalScrollView
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                >
                <!--TODO(3):Update the view as a Linear Layout-->
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:id="@+id/event_participants"
                    android:orientation="horizontal"
                    >
                </LinearLayout>
            </HorizontalScrollView>
        </LinearLayout>

    </LinearLayout>
</android.support.v7.widget.CardView>

请注意,我已尝试使用 TextView 而不是 LinearLayout 的代码版本,在该版本中我将所有名称连接成一个完整的字符串,效果非常好。

我现在正在尝试为每个名称创建一个 TextView 并将其添加到线性布局中。

【问题讨论】:

    标签: java android android-layout nullpointerexception android-context


    【解决方案1】:

    发生这种情况是因为您从未在适配器中设置上下文。 在适配器中添加构造函数并设置 Context 变量。

    public class RVAdapter extends RecyclerView.Adapter<RVAdapter.EventViewHolder> {
    
        Context context;
    
        public RVAdapter(Context context,...){
    
            this.context = context
        }
    }
    
    
    RVAdapter adapter = new RVAdapter(this,events);
    

    【讨论】:

      【解决方案2】:

      试试这个:从活动传递上下文并在适配器构造函数中获取它

      RVAdapter adapter = new RVAdapter(this,events); //add thia line in MainActivity.this
      

      在适配器中添加这个

      RVAdapter(Context context,List<Event> event){
            this.context=context;
            this.events = events;
      }
      

      【讨论】:

        【解决方案3】:

        像这样将Context 添加到您的RVAdapter 构造函数中:

        RVAdapter(List<Events> events, Context context){
            this.events = events;
            this.events = events;
        }
        

        【讨论】:

          【解决方案4】:

          像这样引用你的EventViewHolder

          public class EventViewHolder extends RecyclerView.ViewHolder {
              CardView cv;
              TextView eventName;
              TextView eventTime;
              TextView eventLocation;
              TextView eventDate;
          
              LinearLayout eventParticipants;
          
          
              EventViewHolder(View itemView) {
                  super(itemView);
                  cv = (CardView) itemView.findViewById(R.id.CardViewItem);
                  eventName = (TextView) itemView.findViewById(R.id.event_name);
                  eventTime = (TextView) itemView.findViewById(R.id.event_time);
                  eventDate = (TextView) itemView.findViewById(R.id.event_date);
                  eventLocation = (TextView) itemView.findViewById(R.id.event_location);
                  eventParticipants = (LinearLayout) itemView.findViewById(R.id.event_participants);
          
              }
          
          }
          

          使用 MainActivity 类传递上下文:

          RVAdapter adapter = new RVAdapter(events, this); 
          

          在您的 RVAdapter 类中:

          private Context context;
          private List<Event> events;
          RVAdapter(List<Event> events, Context context){
                this.events = events;
                this.context=context;
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多