50

Tôi có một ứng dụng máy tính bảng đang hoạt động mà hiện tôi đang cố gắng thực hiện công việc trên điện thoại. Trên bàn có hai đoạn trên màn hình một đoạn danh sách và một đoạn chi tiết. Khi trên điện thoại, phân đoạn danh sách xuất hiện và tạo một hoạt động mới khi nhấn một mục danh sách. Hoạt động này chỉ đơn giản là tạo ra các mảnh trong phương pháp onCreate() và cam kết nó vào màn hình như sau.getView trả về null khi phân đoạn đã được tạo từ một hoạt động

// Place an DeallDetailsFragment as our content pane 
DealDetailsFragment f = new DealDetailsFragment(); 
getFragmentManager().beginTransaction().add(android.R.id.content, f).commit(); 
getFragmentManager().executePendingTransactions(); 

Điều này vẫn hoạt động như mong đợi từ hoạt động này tôi cần nói chi tiết về tải và hiển thị. Trong lớp DealDetailsFragment của tôi, tôi có phương thức updateDeal() cập nhật nội dung như sau.

if (deal==null) { // could be null if user presses the loading deals list item before it loads 
    return; 
} 
this.deal=deal; 
if (dealTitle==null) { // get the view objects only once 
    holder = new ViewHolder(); 
    holder.dealHeat=(TextView) getView().findViewById(R.id.dealDetails_heat_textView); 
    holder.dealPrice=(TextView) getView().findViewById(R.id.dealDetails_price_textView); 
    holder.dealRetailer=(TextView) getView().findViewById(R.id.dealDetails_retailer_textView); 
    holder.dealTitle=(TextView) getView().findViewById(R.id.dealDetails_title_textView); 
    holder.dealDesc=(TextView) getView().findViewById(R.id.dealDetails_desc_textView); 
    holder.goToButton= (LinearLayout) getView().findViewById(R.id.dealDetails_goToDeal); 
    holder.dealImage=(ImageView) getView().findViewById(R.id.dealDetails_imageView); 
    holder.postedBy=(TextView) getView().findViewById(R.id.dealDetails_poster_textView); 
    holder.datePosted=(TextView) getView().findViewById(R.id.dealDetails_date_textView); 

getView() sẽ trả về khi ứng dụng được chạy trên điện thoại chỉ có một đoạn được hiển thị.

Bất kỳ ý tưởng nào? Thật không may, không có nhiều ví dụ phân đoạn có sẵn trực tuyến.

+0

Tại điểm nào trong vòng đời Fragment là phương thức updateDeal được gọi? –

+0

Khi đoạn đã được tạo và được nạp. – bencallis

+1

phương pháp cụ thể là gì? onCreate? onCreateView? băt đâu? onResume? –

Trả lời

110

Di chuyển cuộc gọi phương thức của bạn được thực hiện trong onCreateView và sử dụng chế độ xem bạn đang tăng để tham chiếu thay vì getView(). Xem vòng đời đoạn để biết thêm thông tin: https://developer.android.com/guide/components/fragments.html#Creating

và tài liệu của getView() đó giải thích tại sao nó trả về null trước khi onCreateView(LayoutInflater, ViewGroup, Bundle) lợi nhuận:

getView() Lấy xem gốc cho bố trí của đoạn (các một được trả về bởi onCreateView (LayoutInflater, ViewGroup, Bundle)), nếu được cung cấp.

https://developer.android.com/reference/android/app/Fragment.html#getView()

+0

Bạn tiết kiệm được ngày của tôi .... không, Tôi tìm thấy câu trả lời này sau khi tôi đào trong năm giờ. darn .. – Youngjae

+1

Hoàn hảo! May mắn thay, nó chỉ quá 1 giờ trước khi tìm câu trả lời này :). –

+2

cách tìm kiếm theo cách này sẽ cung cấp chế độ xem mới, nhưng tôi muốn tham chiếu về cùng một chế độ xem ?? –

18

Di chuyển các phương pháp để onCreateView() không giúp me.so ... Tạo một biến toàn cầu mView

protected View mView; 

và trong onCreateView()

@Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     Log.d(TAG, "oncreateView"); 
     super.onCreateView(inflater, container, savedInstanceState); 

     View view = inflater.inflate(R.layout.activity_secure_cloud_drive_folder, container, false); 
     this.mView = view; 
     return view; 
} 

và thay thế tất cả getView() của bạn bằng mView

+1

Ngoài ra, đặt mView = null bên trong phương thức onDetach() để tránh rò rỉ bộ nhớ –

4

Bạn phải kiểm tra Vòng đời Android để hiểu TẠI SAO nó là null trên onAttach (...) chức năng.

Hàm đầu tiên được gọi là khi phân đoạn được tạo được thêm là trênAttach(), nhưng thực tế không có chế độ xem nào được tạo. Đó là lý do tại sao null được trả lại khi bạn cố truy cập trong cuộc gọi này.

Chức năng tiếp theo là onCreate() ... nhưng chưa có chế độ xem nào được tạo !!!!

Hàm thứ ba được gọi là onCreateView() và ở đây bạn phải chỉ ra chế độ xem được gắn với đoạn này .... Và chỉ từ cuộc gọi này, nơi đối tượng xem tồn tại và có thể truy cập .

Đọc và tìm hiểu toàn bộ vòng đời here.

Greetings

4

Bạn có thể khắc phục điều đó bằng cách đặt mã của bạn bên trong onViewCreated() -method, mà bạn nên ghi đè. Đừng quên gọi super() trên đó.

+0

Bằng cách nào đó đây là câu trả lời hay nhất và được đánh giá thấp. Tôi không thấy lý do tại sao bạn nên đặt mã của bạn trong onCreateView nếu nó không có gì để làm với lạm phát. Bạn chỉ nên nghiêm túc hơn một chút, thay thế "thực hiện X-things bằng cách" đặt mã của bạn vào phương thức onViewCreated ". – HopefullyHelpful

+0

Có những tình huống mà bạn cần 'getView()' bên ngoài các phương thức vòng đời. –

0

nó trở thành vô lý cơ bản vì bạn gọi getview() trước khi chế độ xem được tăng cao. Tạo một đối tượng View và điền bằng inflater và sau đó tìm yếu tố giao diện người dùng của bạn xem code dưới đây

View view = inflater.inflate(R.layout.fragment_albumslist, container, false); 
     TextView t= (TextView)view.findViewById(R.id.txtTest); 
     t.setText(strtext); 
     return view; 
1

Vì onCreate() được gọi trước khi onCreateView(), cho dù bạn thổi phồng một cái nhìn trong onCreateView() hay không, bạn sẽ không nhận được gì thông qua getView() trong onCreate(), bởi vì trong thời gian đó, onCreate() chưa được gọi là.

Android Lifecycle

+0

Tôi nghĩ bạn nên thêm một nguồn hoặc một cái gì đó như thế này: http://i.imgur.com/6Jl56FA.jpg – Teocci

+0

cảm ơn, điều đó làm cho nó rõ ràng hơn –

Các vấn đề liên quan